home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / hardware / rap / rap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  88.0 KB  |  3,251 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*****************************************************************************
  18.  *                                                                           
  19.  *          Roland RAP-10 Music Card Device Driver for Eisa Bus              
  20.  *        ---------------------------------------------------
  21.  *                                                                           
  22.  *   INTRODUCTION:                                       
  23.  *   -------------
  24.  *   This file contains the device driver for Roland RAP-10                  
  25.  *   Music Card. Currently it contains necessary routines to Record and      
  26.  *   Playback a  Wave file. The MIDI Implementation is to be defined and     
  27.  *   implemented at later time.
  28.  *
  29.  *   DESIGN OVERVIEW:
  30.  *   ----------------
  31.  *   We will use DMA for wave data movements. At any given time, the card
  32.  *   can be either playing or recording and both operations are not allowed.
  33.  *   Also no more than one process at a time can access the card. 
  34.  *
  35.  *   Circular Buffers:
  36.  *   ----------------- 
  37.  *   Since DMA operation is performed independently of the processor,
  38.  *   we will buffer the user's data and release the user's process to
  39.  *   do other things (i.e. preparing more data). Internally we use a 
  40.  *   circular queue (rwQue) to store the data to be played or recorded.
  41.  *   Each entry in this queue is of the type rwBuf_t where the data will
  42.  *   be stored.  Each entry can store up to RW_BUF_SIZE bytes of data.
  43.  *   At the init time, we try to allocate two DMA channels for the card:
  44.  *   Channel 5 and 6. If we can only allocate Channel 5, we will use the
  45.  *   card in Mono mode, otherwise, we will use it as Stereo. DMA has two
  46.  *   buffers of its own: dmaRigh[] and dmaLeft[] for each Channel. For 
  47.  *   Stereo play, the data user provides us is of the format:
  48.  *
  49.  *    <Left Byte><Right Byte><Left Byte><Right Byte>.....
  50.  *   So for playing, we have to move all Left_Bytes to dmaLeft buffer
  51.  *   and all Right_Bytes to the dmaRight buffer (in Stereo mode only).
  52.  *   In mono mode, we will use dmaLeft[] buffer and all the user's data
  53.  *   are moved to dmaLeft[].
  54.  *
  55.  *   The basic operation of the Card are as follow:
  56.  *    
  57.  *    Playing:
  58.  *    --------
  59.  *    For playing wave data, the user must first open the card through
  60.  *    open() system call.The call comes to us as rapopen(). This 
  61.  *    routine resets all global values, states and counters, prepares
  62.  *    necessary DMA structures for each channel, disables RAP-10 
  63.  *    interrupts and establishes this process as the owner of the card.
  64.  *      
  65.  *    The user provides us with the wave data by issuing write()
  66.  *    system calls. This call comes to us as rapwrite(). We will
  67.  *    move the data from user's address space into an empty rwQue[]
  68.  *    entry and will retrun so that the user can issue another call.
  69.  *    If there is no DMA going, we will start one and the data will
  70.  *    start to be moved to the Card to be played. 
  71.  *    The user can issue as many write() as necessary. The playing 
  72.  *    operation will be done by either closing the card or issuing
  73.  *    an Ioctl call. Issuing Ioctl, will leave this process as owner
  74.  *    still while closing the card will release the card. 
  75.  *
  76.  *    Recording:
  77.  *    ----------
  78.  *    Assuming that the user has opened the card and is the current
  79.  *    owner, user will issue read() system call. The call comes to
  80.  *    us as rapread(). If no DMA Record is going on, we will start 
  81.  *    one. We will move data from rwQue[] entries (as they are filled)
  82.  *    to user's address space. The recording is done either by a 
  83.  *    close() or ioctl() call.
  84.  *
  85.  *
  86.  *   DMA Starting:
  87.  *   -------------
  88.  *   For Playing, we will start DMA when we have a full circular buffer.
  89.  *   This is done so that we have enough data available for a fast DMA
  90.  *   operation to be busy with. For recording, we will start DMA 
  91.  *   immediatly. 
  92.  *
  93.  *   Interrupts:
  94.  *   -----------
  95.  *   For each DMA transfer, we will receive two interrupts: One when 1st
  96.  *   half the buffer is transfered, one when 2nd half of the buffer is 
  97.  *   transfered.  We must fill the half that has just been transfered with
  98.  *   fresh data.  Note that in Stereo mode, there are two DMA operation
  99.  *   going. So when we receive Interrupt for one DMA, we must wait for the
  100.  *   exact interrupt from the other DMA and service both DMA's half buffers.
  101.  *
  102.  *   Card Address and IRQ
  103.  *   --------------------
  104.  *   We will use the default bus address of 0x330 and IRQ 5. Change in 
  105.  *   bus address should also be reflected in /var/sysgen/system/rap.sm 
  106.  *   file.  Changes in IRQ should be reflected in the source code and 
  107.  *   the program must be recomplied.
  108.  *
  109.  *   ISSUES:
  110.  *   -------
  111.  *       1. The DMA processing and transfer of data from/to user's buffer
  112.  *       are independent of each other. When we are servicing the 
  113.  *       one half of the dma buffer that just been transfered, there is
  114.  *       no guarantee that we can fill that half of the buffer BEFORE
  115.  *       dma is done with the other half. In this case, dma plays the 
  116.  *       fist half of buffer WHILE we are writing into it.
  117.  *
  118.  *    2. Currently eisa_dma_disable() routine does not actually
  119.  *       releases the Dma channels. This is the reason why we access
  120.  *       the Dma channel table (e_ch[]) ourselves and release the 
  121.  *       channel.
  122.  *
  123.  *    3. Somehow because of number 2, the Play program cannot be 
  124.  *       stopped with a Ctrl-C. In Play program this signal is 
  125.  *       explicitly ignored. Trapping a Ctrl-C causes a kernel panic.
  126.  *       Once we have a workable eisa_dma_disable(), this problem will
  127.  *       be resolved.
  128.  *
  129.  *
  130.  *   TECHNICAL REFERENCES:
  131.  *   ---------------------
  132.  *   Roland RAP-10 Technical Reference and Programmer's Guide, Ver. 1.1
  133.  *   IRIX Device Driver Programming Guide
  134.  *   IRIX Device Driver Reference Pages.
  135.  *   Intel 82357 Preliminary Reference, Section: 3.7.8 Mode Register (pp: 223)
  136.  *
  137.  ******************************************************************************
  138.  ***                                        ***
  139.  ***    Copyright 1994, Silicon Graphics Inc., Mountain View, CA.           ***
  140.  ***                                        ***
  141.  ******************************************************************************
  142.  */ 
  143.  
  144.  
  145. #include "sys/types.h"
  146. #include "sys/file.h"
  147. #include "sys/errno.h"
  148. #include "sys/open.h"
  149. #include "sys/conf.h"
  150. #include "sys/cmn_err.h"
  151. #include "sys/debug.h"
  152. #include "sys/param.h"
  153. #include "sys/edt.h"
  154. #include "sys/pio.h"
  155. #include "sys/uio.h"
  156. #include "sys/proc.h"
  157. #include "sys/user.h"
  158. #include "sys/eisa.h"
  159. #include "sys/sema.h"
  160. #include "sys/buf.h" 
  161. #include "sys/cred.h"
  162. #include "sys/kmem.h"
  163. #include "sys/ddi.h"
  164.  
  165. #include "./rap.h"
  166.  
  167.  
  168. /*
  169.  *    Macros to Read/Write 8 and 16-bit values from an address
  170.  */
  171.  
  172. #define OUTB(addr, b)  ( *(volatile uchar_t *)(addr) = (b) )
  173. #define INPB(addr)     ( *(volatile uchar_t *)(addr) )
  174. #define OUTW(addr, w)  ( *(volatile ushort_t *)(addr) = (w) )
  175. #define INPW(addr)     ( *(volatile ushort_t *)(addr) )
  176.  
  177. /*
  178.  *    Raising and lowering CPU interrupt
  179.  */
  180. #define LOCK()     spl5();
  181. #define UNLOCK(s)  splx(s);
  182. #define FROM_INTR  1
  183. #define FROM_USR   0
  184.  
  185. #define User_pid   u.u_procp->p_pid
  186.  
  187. /*
  188.  *   IRQ and DMA channels we need. 
  189.  *   
  190.  */
  191. #define IRQ_MASK     0x0020        
  192. #define DMAC_CH5        0x20     /*  DMA Channel 5   */
  193. #define DMAC_CH6        0x40     /*  DMA Channel 6   */
  194.  
  195.  
  196. /*=======================================* 
  197.  *       MIDI and RAP Registers      *
  198.  *=======================================* 
  199.  *
  200.  *    The following is a description of RAP-10 registers. The same
  201.  *    names used throughout this program. Some of these registers are
  202.  *    8-bit and some are 16-bit long. 
  203.  *
  204.  *        mdrd:    MIDI Receive Data
  205.  *        mdtd:    MIDI Transmit Data
  206.  *        mdst:    MIDI Status 
  207.  *        mdcm:    MIDI Command
  208.  *        pwmd:     Pulse Width Modulation Data
  209.  *        timm:     Timer MSB data
  210.  *        gpcm:     GPCC Command
  211.  *        dtci:     DMA Transfer Count Buffer Interrupt Status
  212.  *        adcm:     GPCC Analog to Digital Command
  213.  *        dacm:     D/A Command and DMA Transfer Configuration
  214.  *        gpis:       GPCC Interrupt Status
  215.  *        gpdi:     GPCC DMA/Interrupt Enable
  216.  *        gpst:     GPCC Status
  217.  *        dad0:     Digital to Analog Data Channel 0
  218.  *        addt:     A/D Data Transfer
  219.  *        dad1:     Digital to Analog Data Channel 1
  220.  *        timd:     Timer Data
  221.  *        cmp0:     Compare Register Channel 0
  222.  *        dtcd:     DMA Transfer Count Data
  223.  *        cmp1:     Compare Register Channel 1
  224.  *        
  225.  *
  226.  *    These defines indicate the offsets of the above registers
  227.  *    from the Drive's base address:
  228.  */
  229.  
  230. #define MDRD    0x0
  231. #define MDTD    0x0
  232. #define MDST    0x1
  233. #define MDCM    0x1
  234. #define PWMD    0x2
  235. #define TIMM    0x3
  236. #define GPCM    0x3
  237. #define DTCI    0x4
  238. #define ADCM    0x4
  239. #define DACM    0x5
  240. #define GPIS    0x6
  241. #define GPDI    0x6
  242. #define GPST    0x8
  243. #define DAD0    0x8
  244. #define ADDT    0xa
  245. #define DAD1    0xa
  246. #define TIMD    0xc
  247. #define CMP0    0xc
  248. #define DTCD    0xe
  249. #define CMP1    0xe
  250.  
  251. typedef struct rapReg {
  252.      uchar_t  mdrd; 
  253.      uchar_t  mdtd;
  254.      uchar_t  mdst; 
  255.      uchar_t  mdcm;
  256.      uchar_t  pwmd; 
  257.      uchar_t  timm; 
  258.      uchar_t  gpcm;
  259.      uchar_t  dtci; 
  260.      uchar_t  adcm;
  261.      uchar_t  dacm; 
  262.      ushort_t gpis;
  263.      ushort_t gpdi; 
  264.      ushort_t gpst;
  265.      ushort_t dad0;
  266.     ushort_t addt;
  267.      ushort_t dad1;
  268.      ushort_t timd;
  269.      ushort_t cmp0; 
  270.      ushort_t dtcd; 
  271.      ushort_t cmp1; 
  272. } rapReg_t;
  273.  
  274. /*==========================================================*
  275.  *            dtct  (DMA Transfer Count)                   *
  276.  *==========================================================*/
  277. #define DTCD_DRQ0  0x00FF   /*  DRQ 0 bits (0-7)  */
  278. #define DTCD_DRQ1  0xFF00   /*  DRQ 1 bits (8-15) */
  279.  
  280.  
  281.  
  282. /*==========================================================*
  283.  *            gpst  (GPCC Status)                          *
  284.  *==========================================================*/
  285. #define GPST_PWM2       0x0800  /* PWM2 Busy (0=Write Enable, 1=Busy)         */
  286. #define GPST_PWM1       0x0400  /* PWM1 Busy (0=Write Enable, 1=Busy)         */
  287. #define GPST_PWM0       0x0200  /* PWM0 Busy (0=Write Enable, 1=Busy)         */
  288. #define GPST_EPB    0x0100  /* EP Convertor Busy (0=Write Enable, 1=Busy) */
  289. #define GPST_GP1    0x0080  /* GP-chip, Ch 1 Acess (1 = Access)           */
  290. #define GPST_GP0    0x0040  /* GP-chip, Ch 0 Acess (1 = Access)  */
  291. #define GPST_MTE    0x0020  /* MIDI Tx Enable (0=Tx_Fifo buff full) */
  292. #define GPST_ORE    0x0010  /* MIDI Overrun Error (1 = error) */
  293. #define GPST_FE        0x0008  /* MIDI Framing Error (1 = error) */
  294. #define GPST_ADE    0x0004    /* A/D Error (1 = error) */
  295. #define GPST_DE1    0x0002    /* D/A Ch 1 Write Error (1 = error) */
  296. #define GPST_DE0    0x0001    /* D/A Ch 0 Write Error (1 = error) */
  297.  
  298.  
  299.  
  300. /*==========================================================*
  301.  *            gpdi  (GPCC DMA/Interrupt Enable (pp: 4-18)  *
  302.  *==========================================================*/
  303. #define GPDI_ITC  0x8000  /* DMA Transfer Cnt Match (0=Disable) */
  304. #define GPDI_DC2  0x4000  /* DMA Chann. Assignment, bit2 (pp:4-18) */
  305. #define GPDI_DC1  0x2000  /* DMA Chann. Assignment, bit1 (pp:4-18) */
  306. #define GPDI_DC0  0x1000  /* DMA Chann. Assignment, bit0 (pp:4-18) */
  307. #define GPDI_DT1  0x0800  /* DMA Trans. Mode, bit:1 (pp: 4-18)     */
  308. #define GPDI_DT0  0x0400  /* DMA Trans. Mode, bit:0 (pp: 4-18)     */
  309. #define GPDI_OVF  0x0200  /* Free Run.Cntr (FCR) Ov.Flow (0=Disable)*/
  310. #define GPDI_TC1  0x0100  /* Timer 1 Compare Match (0=Disable)      */
  311. #define GPDI_TC0  0x0080  /* Timer 0 Compare Match (0=Disable)      */
  312. #define GPDI_RXD  0x0040  /* MIDI Data Read Request (0=Disable)     */
  313. #define GPDI_TXD  0x0020  /* MIDI Tx_fifo Buf Empty (0=Disable)     */
  314. #define GPDI_ADD  0x0010  /* A/D Data Ready (0=Disable)            */
  315. #define GPDI_DN1  0x0008  /* D/A Ch1 Note ON Ready (0=Disable)      */
  316. #define GPDI_DN0  0x0004  /* D/A Ch0 Note ON Ready (0=Disable)      */ 
  317. #define GPDI_DQ1  0x0002  /* D/A Ch1 Data Request  (0=Disable)      */
  318. #define GPDI_DQ0  0x0001  /* D/A Ch0 Data Request  (0=Disable)      */
  319.  
  320.  
  321.  
  322. /*==========================================================*
  323.  *            gpis  (GPCC Interrupt Status .. pp: 4-16)    *
  324.  *==========================================================*/
  325. #define GPIS_ITC    0x8000  /*  DMA Transfer Count Match   */
  326. #define GPIS_JSD    0x0400  /*  Joystick Data Ready        */
  327. #define GPIS_OVF        0x0200  /*  Free Running Countr Overflow */
  328. #define GPIS_TC1    0x0100  /*  Timer1 Compare Match         */
  329. #define GPIS_TC0    0x0080    /*  Timer0 Compare Match     */
  330. #define GPIS_RXD        0x0040  /*  MIDI Data Read Request     */
  331. #define GPIS_TXD    0x0020  /*  MIDI Tx_fifo Buf. Empty      */
  332. #define GPIS_ADD    0x0010  /*  A/D Data Ready         */
  333. #define GPIS_DN1    0x0008  /*  D/A Ch1 Note ON Ready     */
  334. #define GPIS_DN0    0x0004  /*  D/A Ch0 Note ON Ready     */
  335. #define GPIS_DQ1    0x0002  /*  D/A Ch1 Data Request   */
  336. #define GPIS_DQ0    0x0001  /*  D/A Ch0 Data Request   */
  337.  
  338.  
  339. /*======================================================================*
  340.  *           dacm (Digital To Analogue Cmd and DMA Transfer Config)    *
  341.  *======================================================================*/
  342. #define DACM_SCC   0x80  /* DMA Size Cmp. Cnt (0=in Sample, 1=in Bytes)*/
  343. #define DACM_TS2   0x40  /* DMA Trnsfr Size, bit 2 (pp: 4-14)   */
  344. #define DACM_TS1   0x20  /* DMA Trnsfr Size, bit 1 (pp: 4-14)   */
  345. #define DACM_TS0   0x10  /* DMA Trnsfr Size, bit 0 (pp: 4-14)   */
  346. #define DACM_DL1   0x08  /* Ch1 DA Data Len (0=8 bit, 1=17 bit) */
  347. #define DACM_DL0   0x04  /* Ch0 DA Data Len (0=8 bit, 1=17 bit) */
  348. #define DACM_DS1   0x02  /* Ch1 DA Convrsion (0=Stop, 1=Start) */
  349. #define DACM_DS0   0x01  /* Ch0 DA Convrsion (0=Stop, 1=Start) */
  350.  
  351.  
  352.  
  353. /*=====================================================*
  354.  *             adcm (  GPCC AD Command )           *
  355.  *=====================================================*/
  356. #define  ADCM_MON    0x40  /* Monitor MIC (0=Monitor Off) */ 
  357. #define  ADCM_GIN    0x20  /* Gain Input (0=Line, 1=Mic)  */
  358. #define  ADCM_AF1    0x10  /* Analog Freq Selection bit 1 (pp: 4-13)*/
  359. #define  ADCM_AF0    0x08  /* Analog Freq Selection bit 0 (pp: 4-13)*/
  360. #define  ADCM_ADL    0x04  /* Analog Data Length (0=8, 1=16)*/
  361. #define  ADCM_ADM    0x02  /* Analog Data Conv. Mode (0=Mono,1=Stereo)*/
  362. #define  ADCM_ADS    0x01  /* Analog Data Conv. Start(0=Stop,1=Start)*/
  363.  
  364. /*=====================================================*
  365.  *            dtci ( DMA Trans.Count Buf Intr. Stat    *
  366.  *=====================================================*/
  367. #define DTCI_BF1        0x08  /* DMA DRQ1 buff full (1 = full) */
  368. #define DTCI_BH1        0x04  /* DMA DRQ1 buff half (1 = full) */
  369. #define DTCI_BF0        0x02  /* DMA DRQ0 buff full (1 = full) */
  370. #define DTCI_BH0        0x01  /* DMA DRQ0 buff half (1 = full) */
  371.  
  372. /*========================================*
  373.  *             gpcm  ( GPCC Command )     *
  374.  *========================================*/
  375. #define GPCM_RST    0x80        /*   Reset bit             */
  376. #define GPCM_PWM2    0x10        /*   Select PWM channel 2     */
  377. #define GPCM_PWM1    0x08        /*   Select PWM channel 1     */
  378. #define GPCM_PWM0    0x04        /*   Select PWM channel 0     */
  379. #define GPCM_FRCM       0x02        /*   Free Run. Counter (1=Start) */
  380. #define GPCM_MTT    0x01        /*   MIDI Timed Trans         */
  381.                     /*   ( 1 = Timer INT enabled )   */ 
  382.  
  383. /*======================================*
  384.  *       timm  (Timer MSB data)         *
  385.  *======================================*/
  386. #define TIMM_FRC        0x04         /*   Free Running Counter Bit 16 */
  387. #define TIMM_CR1    0x02        /*   Compare Reg 1 Bit 16     */
  388. #define TIMM_CR0    0x01        /*   Compare Reg 0 Bit 16     */
  389.  
  390. /*===================================*
  391.  *      mdcm (MIDI Command)          *
  392.  *===================================*/
  393. #define MDCM_UART    0x3f        /*   UART mode            */
  394. #define MDCM_MPU    0xff        /*   MPU Reset            */
  395. #define MDCM_VERSION    0xac        /*   Version            */
  396. #define MDCM_REVISION    0xad        /*   Revision            */
  397.  
  398. /*===================================*
  399.  *        mdst (MIDI Status)         *
  400.  *===================================*/
  401. #define  MDST_DSR    0x80         /*  DSR = 0 if ready            */
  402. #define  MDST_DDR       0x40         /*  DDR = 0 if ready        */
  403.  
  404. /*====================================*
  405.  *      RAP Card Info                 *
  406.  *====================================*
  407.  *
  408.  *   These are the information regarding the RAP Card.
  409.  *   The info being tracked are:
  410.  *
  411.  *    ci_state:   Our state (Installed, Opened, Playing, Recording)
  412.  *      ci_pid:     PID of process opened us.
  413.  *    ci_addr[]:  EISA  Addresses
  414.  *    ci_irq:     EISA Interrupt number we use
  415.  *    ci_ctl:     Controller number we save from edt struct
  416.  *    ci_adap:    Adaptor number we save from edt struct.
  417.  *      ci_dmaCh6:  DMA Channel 6
  418.  *    ci_dmaCh5:  DMA Channel 5
  419.  *    ci_dmaBuf6: EISA DMA Buffer struct for Channel 6
  420.  *    ci_dmaBuf5: EISA DMA Buffer struct for Channel 5
  421.  *    ci_dmaCb6:  EISA DMA Control Block for Channel 6
  422.  *    ci_dmaCb5:  EISA DMA Control Block for Channel 5
  423.  *
  424.  *    di_state:   DMA buffers state (Idle, Progress)
  425.  *    di_idx:   Current rwQue[] entry being used.
  426.  *    di_ptr:   Address in rwQue buffer       
  427.  *    di_which:   Which half of DMA buffer (0=1st half, 1=2nd Half)
  428.  *    di_bh:      Total DMA Buffer Half (BH) Interrupt received.
  429.  *    di_bf:      Total DMA Buffer Full (BF) Interrupt received.
  430.  *
  431.  *    ri_state:   State of Circular buffer (Wanted_Empty, etc.)
  432.  *    ri_free:    Total Free entries in rwQue[]
  433.  *    ri_full:    Total Full entries in rwQue[]
  434.  *    ri_idx:     Current rwBuf for Read/Write
  435.  *    ri_tout;    =1 if Timed out on read/write
  436.  *    ri_note;    number of Note_On received
  437.  *    ri_ptr:     Pointer in current rwBuf
  438.  */
  439.  
  440. typedef  struct eisa_dma_buf   dmaBuf_t;
  441. typedef  struct eisa_dma_cb    dmaCb_t;
  442.   
  443. typedef struct cardInfo_s {
  444.  
  445.     /*   Card Installation Info   */
  446.     ushort_t   ci_state;
  447.     pid_t      ci_pid;
  448.     caddr_t    ci_addr[NBASE];
  449.     int       ci_irq;
  450.     int       ci_ctl;
  451.     int       ci_adap;
  452.     int       ci_dmaCh6;
  453.     int       ci_dmaCh5;
  454.     dmaBuf_t   *ci_dmaBuf6;
  455.     dmaBuf_t   *ci_dmaBuf5;
  456.     dmaCb_t    *ci_dmaCb6;
  457.     dmaCb_t    *ci_dmaCb5;
  458.  
  459.     /*   DMA Buffer Information data */
  460.     uchar_t   di_state;
  461.     short     di_idx;
  462.     uchar_t      di_which;
  463.     caddr_t   di_ptr;
  464.     uchar_t   di_bh; 
  465.     uchar_t   di_bf; 
  466.  
  467.     /*   Circular buffer Information data */
  468.     uchar_t   ri_state;
  469.     short     ri_free;
  470.     short     ri_full;
  471.     short     ri_idx;
  472.     uchar_t   ri_tout;
  473.     uchar_t      ri_note;
  474.     caddr_t   ri_ptr;
  475.  
  476. } cardInfo_t;
  477.  
  478. /*   ci_state  values   */
  479. #define  CARD_INSTALLED    0x0001
  480. #define  CARD_STEREO       0x0002
  481. #define  CARD_OPENED       0x0004
  482. #define  CARD_PLAYING      0x0010
  483. #define  CARD_RECORDING    0x0020
  484.  
  485.  
  486. /*   di_state values    */
  487. #define  DI_DMA_IDLE       0x00   
  488. #define  DI_DMA_PLAYING    0x01
  489. #define  DI_DMA_RECORDING  0x02
  490. #define  DI_DMA_END_PLAY   0x04
  491. #define  DI_DMA_END_RECORD 0x08
  492.  
  493.  
  494. /*   ri_state values   */
  495. #define RI_WANTED_EMPTY    0x01
  496.  
  497. /*====================================*
  498.  *      Read/Write Circular Buffers   *
  499.  *====================================*
  500.  *
  501.  *    This is the description of our circular buffers used
  502.  *    to store D/A and A/D values. D/A values are stored from 
  503.  *    user's buffer and then moved to DMA buffers. A/D data is
  504.  *    moved from DMA buffers to these buffers and then moved 
  505.  *    to user's buffer. The fields are as follow:
  506.  *
  507.  *        rw_state:    buffer state (Empty, Busy, Full)
  508.  *        rw_idx:         Index of this buffer in rwQue[]; 
  509.  *        rw_count:    Total bytes in the buffer
  510.  *        rw_buf[]:    The buffer itself.
  511.  *
  512.  *      RW_MIN_FULL:  We will start a D/A DMA when we have this many
  513.  *              full buffer on hand. This is done so that we can 
  514.  *              provide enough full buffers for DMA to process.
  515.  */
  516.  
  517. #define  RW_BUF_SIZE    8192
  518. #define  RW_BUF_COUNT   20
  519. #define  RW_MIN_FULL    1 
  520. #define  RW_TIMEOUT     1600
  521.  
  522. typedef struct rwBuf_s {
  523.     uchar_t        rw_state;
  524.     short       rw_idx;
  525.     int        rw_count;
  526.     uchar_t        rw_buf[RW_BUF_SIZE];
  527. } rwBuf_t;
  528.  
  529. /*   rw_state  values   */
  530. #define RW_EMPTY        0x00  /*  used as parameter only  */
  531. #define RW_FULL         0x01
  532. #define RW_WANTED_FULL  0x02
  533. #define RW_WANTED_EMPTY 0x04
  534.  
  535.  
  536. /*==================================*
  537.  *         Global values            *
  538.  *==================================*/
  539.  
  540. #define   DMA_BUF_SIZE        8192
  541. #define   DMA_HALF_SIZE       4096
  542.  
  543. int                  rapdevflag = 0;
  544. static cardInfo_t    cardInfo;
  545. static caddr_t       dmaRight;
  546. static caddr_t       dmaLeft;
  547. static paddr_t       dmaRightPhys;
  548. static paddr_t       dmaLeftPhys;
  549. static rwBuf_t       rwQue[RW_BUF_COUNT];
  550. static caddr_t       eisa_addr;
  551.  
  552. /*
  553.  *    Eisam Dma Channel semaphores..shoule be removed when
  554.  *    proper way of releasing channels found
  555.  */
  556. extern struct eisa_ch_state {
  557.         sema_t chan_sem;                /* inuse semaphore for each channel */
  558.         sema_t dma_sem;                 /* dma completion semaphore */
  559.         struct eisa_dma_buf *cur_buf;   /* current eisa_dma_buf being dma'ed */
  560.         struct eisa_dma_cb *cur_cb;     /* ptr to current command block */
  561.         int    count;
  562. } e_ch[];
  563.  
  564.  
  565. /*=========================================*
  566.  *        Driver Entry routines Data       *
  567.  *=========================================*/
  568.  
  569. int    rapopen  ( dev_t *, int, int, cred_t  * );
  570. int    rapread ( dev_t, uio_t *, cred_t * );
  571. int    rapwrite ( dev_t, uio_t *, cred_t * );
  572. int    rapclose ( dev_t, int, int, cred_t  * );
  573. void   rapedtinit ( struct edt  * );
  574. void   rapintr ( int );
  575. int    rapioctl (dev_t, int, void *, int, cred_t *, int *);
  576.  
  577.  
  578. /*=======================================*
  579.  *     Misc and Internal routines       *
  580.  *=======================================*/
  581.  
  582. static void   rapDisInt (cardInfo_t  *);
  583. static int    rapGetDma( dmaBuf_t  **,  dmaCb_t **, int );
  584. static int    rapClose(uchar_t);
  585. static short  rapGetNextEmpty (short, uchar_t);
  586. static short  rapGetNextFull (short, uchar_t);
  587. static void   rapPrepEisa( dmaBuf_t *, dmaCb_t *, uchar_t, paddr_t);
  588. static int    rapStart(uchar_t);
  589. static void   rapStop(uchar_t);
  590. static void   rapStartDA();
  591. static void   rapStartAD();
  592. static void   rapBufToDma( int );
  593. static void   rapDmaToBuf( int );
  594. static void   rapMarkBuf(rwBuf_t *, cardInfo_t *, uchar_t);
  595. static int    rapKernMem(uchar_t);
  596. static void   rapSetAutoInit(cardInfo_t *, uchar_t);
  597. static void   rapTimeOut( void *);
  598. static void   rapNoteOn(cardInfo_t *, ushort_t );
  599. static void   rapNoteOff(cardInfo_t *);
  600. static void   rapZeroDma(cardInfo_t *, int);
  601. static void   rapReleaseDma (cardInfo_t *);
  602.  
  603.  
  604.  
  605.  
  606. /*************************************************************************
  607.  *        r a p e d t i n i t 
  608.  *************************************************************************
  609.  *
  610.  *   Name:      rapedtint
  611.  *    
  612.  *   Purpose:   Initializes the driver. Called once for each controller.
  613.  *        Called only once.
  614.  *
  615.  *   Returns:   None.
  616.  *
  617.  *************************************************************************/
  618.  
  619. void 
  620. rapedtinit ( struct edt *e )
  621. {
  622.     int         ctl, iospace, dmac, eirq;
  623.     cardInfo_t   *ci;  
  624.     piomap_t      *pmap;
  625.         iospace_t     eisa_io;
  626.  
  627.  
  628.     ci = &cardInfo;
  629.  
  630.     cmn_err (CE_NOTE, "rapedtinit: Installing RAP board.");
  631.     bzero ((void *)ci, sizeof(cardInfo_t) );    
  632.     dmaRight = dmaLeft = (caddr_t)NULL;
  633.     ci->ci_ctl = e->e_ctlr;
  634.     ci->ci_adap = e->e_adap;
  635.  
  636.         /*
  637.          *    Get the base address of Eisa bus (for rapSetAutoInit)
  638.          */
  639.         bzero (&eisa_io, sizeof(iospace_t));
  640.         eisa_io.ios_iopaddr = 0;
  641.         eisa_io.ios_size    = 1000;
  642.  
  643.         pmap = pio_mapalloc (e->e_bus_type, 0, &eisa_io, PIOMAP_FIXED, "eisa");
  644.         if ( pmap == (piomap_t *)NULL ) {
  645.                 cmn_err (CE_WARN, "rapedtinit: Cannot get Eisa bus address");
  646.                 return;
  647.         }
  648.  
  649.         eisa_addr = pio_mapaddr (pmap, eisa_io.ios_iopaddr);
  650.  
  651.         #ifdef DEBUG
  652.         cmn_err (CE_NOTE, "rapedtinit: Eisa base address = %x", eisa_addr);
  653.         #endif
  654.  
  655.     /*===================================================*
  656.      *   map EISA IO/Memory addresses for RAP-10 card    *
  657.      *===================================================*/
  658.     for ( iospace = 0; iospace < NBASE; iospace++ ) {
  659.  
  660.         /*  any address to map ?    */
  661.         if ( !e->e_space[iospace].ios_iopaddr )
  662.             continue;
  663.  
  664.         pmap = pio_mapalloc ( e->e_bus_type, e->e_adap,
  665.                       &e->e_space[iospace], 
  666.                       PIOMAP_FIXED, "rap10" );
  667.  
  668.         ci->ci_addr[iospace] = pio_mapaddr ( pmap, 
  669.                      e->e_space[iospace].ios_iopaddr );
  670.     }
  671.  
  672.     /*  is Card still there  ? */
  673.     if ( badaddr(ci->ci_addr[0], 1) ) {
  674.         cmn_err (CE_WARN, "rapedtinit: RAP board not installed.");
  675.         return;
  676.     }
  677.  
  678.     #ifdef DEBUG   
  679.     cmn_err (CE_NOTE, "rapedtinit: First Load..allocating IRQ");
  680.     #endif
  681.  
  682.     eirq = eisa_ivec_alloc( e->e_adap, IRQ_MASK, EISA_EDGE_IRQ );
  683.     
  684.     if ( eirq < 0 ) {
  685.         cmn_err (CE_WARN, 
  686.         "rapedtinit: Could not allocate IRQ for RAP card.");
  687.         return;
  688.     }
  689.  
  690.     /*    set Interrupt handler     */
  691.         #ifdef DEBUG   
  692.         cmn_err (CE_NOTE, "rapedtinit: Setting Interrupt Handler for IRQ %d",
  693.               eirq); 
  694.         #endif
  695.  
  696.     if ( eisa_ivec_set(e->e_adap, eirq, rapintr, e->e_ctlr) == -1 ) {
  697.         cmn_err (CE_NOTE, 
  698.         "rapedtinit: Could not set Interrupt handler for Irq %d", eirq);
  699.         ci->ci_state = 0;
  700.         return;
  701.     }
  702.  
  703.     ci->ci_irq = eirq;
  704.  
  705.     
  706.     /*======================================*    
  707.      *    DMA Channels Allocation            *    
  708.      *======================================*/
  709.  
  710.     /*   DMA channel 5 */
  711.     dmac = eisa_dmachan_alloc ( e->e_adap, DMAC_CH5 );
  712.     if ( dmac < 0 ) {
  713.         cmn_err (CE_WARN, 
  714.              "rapedtinit: Could not allocate DMA Channel 5.");
  715.         return;
  716.     }
  717.  
  718.     ci->ci_dmaCh5 = dmac;
  719.  
  720.     /*   DMA channel 6  */ 
  721.     dmac = eisa_dmachan_alloc ( e->e_adap, DMAC_CH6 );
  722.     if ( dmac < 0 ) {
  723.         cmn_err (CE_WARN, 
  724.              "rapedtinit: Could not allocate DMA Chann 6."); 
  725.         cmn_err (CE_WARN, 
  726.              "rapedtinit: RAP is initialized as Mono.");
  727.     }
  728.     else {
  729.         ci->ci_dmaCh6 = dmac;
  730.         ci->ci_state |= CARD_STEREO;
  731.     }
  732.  
  733.     /*==============================*
  734.      *      DMA Buffer allocation   * 
  735.      *==============================*/
  736.  
  737.     if ( rapKernMem (1) ) {
  738.         cmn_err (CE_WARN, "rapedtinit: Did not install RAP-10.");
  739.         return;
  740.     }
  741.  
  742.     ci->ci_state |= CARD_INSTALLED; 
  743.  
  744. #ifdef DEBUG
  745.     cmn_err (CE_NOTE, "rapedtinit: RAP installed, Addr: %x, Irq: %d.",
  746.          ci->ci_addr[0], ci->ci_irq );
  747.  
  748.     cmn_err (CE_NOTE, "rapedtinit: Init as %s, Dma 1 = %d, Dma 0 = %d",
  749.          (ci->ci_state & CARD_STEREO ? "Stereo":"Mono"), 
  750.           ci->ci_dmaCh5, ci->ci_dmaCh6);
  751. #endif
  752.  
  753.     return;
  754.  
  755. }  /***   End rapedtinit    ***/
  756.  
  757.  
  758.  
  759. /*************************************************************************
  760.  *            r a p o p e n                 
  761.  *************************************************************************
  762.  *
  763.  *  Name:      rapopen 
  764.  *    
  765.  *  Purpose:   Opens the RAP board and initializes necessary data
  766.  *
  767.  *  Returns:   0 = Success, or appropriate error number.
  768.  *
  769.  *************************************************************************/
  770. int
  771. rapopen ( dev_t  *dev, int oflag, int otyp, cred_t  *cred)
  772. {
  773.     register int    i;
  774.         cardInfo_t      *ci;
  775.     rwBuf_t         *rw;
  776.         dmaBuf_t        *dmaB;
  777.         dmaCb_t         *dmaC;
  778.  
  779.  
  780.     ci = &cardInfo;
  781.  
  782. #ifdef DEBUG
  783.         cmn_err (CE_NOTE, "rapopen: Opening, Addr = %x, ci_state = %x",
  784.                  ci->ci_addr[0], ci->ci_state );
  785. #endif
  786.  
  787.     /*
  788.      *  No card is installed or card is already opened 
  789.      */
  790.     if ( !(ci->ci_state & CARD_INSTALLED) )
  791.         return (ENODEV);
  792.  
  793.     if ( ci->ci_state & CARD_OPENED ) 
  794.         return (EBUSY);
  795.  
  796.  
  797.     /*   Allocate DMA Buf and Cb for Channel 5  */
  798.         if ( ci->ci_dmaBuf5 == (dmaBuf_t *)NULL ) {
  799.                 if ( rapGetDma(&dmaB, &dmaC, ci->ci_dmaCh5) ) {
  800.                         cmn_err (CE_WARN,
  801.                                  "rapoen: Could not allocate DMA Buf 5.");
  802.                         return (ENOMEM);
  803.                 }
  804.  
  805.                 ci->ci_dmaBuf5 = dmaB;
  806.                 ci->ci_dmaCb5  = dmaC;
  807.         }
  808.  
  809.         /*   if in stereo, do the same for Channel 6  */ 
  810.         if ( ci->ci_state & CARD_STEREO ) {
  811.                 if ( rapGetDma(&dmaB, &dmaC, ci->ci_dmaCh6) ) {
  812.                         cmn_err (CE_WARN,
  813.                                  "rapopen: Could not allocate DMA Buf 6.");
  814.                         return (ENOMEM);
  815.                 }
  816.  
  817.                 ci->ci_dmaBuf6 = dmaB;
  818.                 ci->ci_dmaCb6  = dmaC;
  819.         }
  820.  
  821.  
  822.     /*   Initialize Card Info structure  */ 
  823.     ci->ri_idx   = 0;
  824.     ci->di_idx   = 0;
  825.     ci->ri_state = 0;
  826.     ci->di_state = 0;
  827.     ci->di_ptr   = 0; 
  828.     ci->ri_ptr   = 0; 
  829.     ci->ri_free  = RW_BUF_COUNT;
  830.     ci->ri_full  = 0;
  831.  
  832.     ci->ci_state &= ~(CARD_PLAYING | CARD_RECORDING );
  833.               
  834.     ci->ci_state |= CARD_OPENED;
  835.     ci->ci_pid    = User_pid; 
  836.  
  837.     /*   Initialize Circular Buffers   */ 
  838.     for ( i = 0; i < RW_BUF_COUNT; i++ ) {
  839.         rw = &rwQue[i];
  840.         rw->rw_count = 0;
  841.         rw->rw_state = 0; 
  842.         rw->rw_idx   = i;
  843.         bzero (rw->rw_buf, RW_BUF_SIZE);
  844.     }
  845.  
  846.  
  847.     rapDisInt(ci); 
  848.     
  849.     #ifdef DEBUG
  850.     cmn_err (CE_NOTE, "rapopen: Opened succesfully");
  851.     #endif
  852.  
  853.     return(0);
  854.  
  855. }  /***  End rapopen  ***/
  856.  
  857.  
  858. /*************************************************************************
  859.  *            r a p w r i t e                    
  860.  *************************************************************************
  861.  *
  862.  *  Name:       rapwrite
  863.  *    
  864.  *  Purpose:    Write entry routine. This routine will transfer user's
  865.  *        data to current or an empty entry in rwQue[] and starts
  866.  *        DMA if none is going.
  867.  *
  868.  *  Returns:    0 = Success, or errno
  869.  *
  870.  *************************************************************************/
  871. int
  872. rapwrite (dev_t  dev, uio_t  *uio, cred_t  *cred)
  873. {
  874.     cardInfo_t    *ci;
  875.     rwBuf_t       *rw;
  876.     toid_t        to_id;
  877.     int          avail, size, totBytes, err, s;
  878.  
  879.     ci = &cardInfo;
  880.  
  881.     /*=========================*
  882.      *    Error Checking       *
  883.      *=========================*/
  884.  
  885.     /*  no card is installed  */
  886.     if ( !(ci->ci_state & CARD_INSTALLED) ) 
  887.         return (ENODEV);
  888.  
  889.     /*  card is not opened */
  890.     if ( !(ci->ci_state & CARD_OPENED) )
  891.         return (EACCES); 
  892.  
  893.     /*  we are not the owner  */
  894.     if ( ci->ci_pid != User_pid ) 
  895.         return (EACCES);
  896.  
  897.     /*  is busy recording  */
  898.     if ( ci->ci_state & CARD_RECORDING )
  899.         return (EACCES);
  900.  
  901.     ci->ci_state |= CARD_PLAYING;
  902.     rw = &rwQue[ci->ri_idx];            
  903.  
  904.     #ifdef DEBUG
  905.     cmn_err (CE_NOTE, 
  906.         "rapwrite: %d bytes, buf = %d, rw_count = %d, free = %d, full = %d",
  907.     uio->uio_resid, ci->ri_idx, rw->rw_count, ci->ri_free, ci->ri_full);
  908.     #endif
  909.  
  910.  
  911.     /*  if it is full, wait till it is Empty   */
  912.     s = LOCK();
  913.     if ( rw->rw_state & RW_FULL ) { 
  914.  
  915.        ci->ri_ptr = NULL; 
  916.            ci->ri_tout = 0;
  917.            to_id = itimeout (rapTimeOut, rw, RW_TIMEOUT, plbase, 0, 0, 0);
  918.  
  919.        while ( (rw->rw_state & RW_FULL) && !ci->ri_tout ) {
  920.  
  921.         #ifdef DEBUG
  922.          cmn_err (CE_NOTE, "rapwrite: waiting for buf %d to be Empty",
  923.              rw->rw_idx );
  924.         #endif    
  925.  
  926.         rw->rw_state |= RW_WANTED_EMPTY;
  927.         if ( sleep (rw, PUSER | PCATCH) ) {
  928.  
  929.             untimeout(to_id);
  930.  
  931.             #ifdef DEBUG
  932.             cmn_err (CE_NOTE, "rapwrite: Interrupted");
  933.             #endif
  934.  
  935.             rw->rw_state &= ~RW_WANTED_EMPTY;
  936.             UNLOCK(s);
  937.             return (EINTR);
  938.         }
  939.  
  940.        } /* while */
  941.  
  942.        untimeout(to_id);
  943.  
  944.  
  945.        /*   we timed out ..couldn't get the buffer  */
  946.            if ( ci->ri_tout ) {
  947.                 #ifdef DEBUG
  948.                 cmn_err (CE_NOTE, "rapwrite: Timed out");
  949.                 #endif
  950.  
  951.         rw->rw_state &= ~RW_WANTED_EMPTY;
  952.         UNLOCK(s);
  953.                 return (EIO);
  954.            }
  955.  
  956.  
  957.     } /*  if (rw->rw_state & RW_FULL */
  958.  
  959.     UNLOCK(s);
  960.  
  961.  
  962.     /*  adjuest the read/write address if necessary */
  963.     if ( ci->ri_ptr == NULL )
  964.         ci->ri_ptr = rw->rw_buf;
  965.  
  966.     totBytes = uio->uio_resid;
  967.  
  968.     while ( totBytes > 0 )  {
  969.         avail = RW_BUF_SIZE - rw->rw_count; 
  970.         
  971.         /*  if this buffer is full, get next buffer */
  972.         if ( avail <= 0 ) {
  973.  
  974.             #ifdef DEBUG
  975.             cmn_err (CE_NOTE, 
  976.             "rapwrite: Buffer %d is Full now, rw_count = %d",
  977.             rw->rw_idx, rw->rw_count);
  978.             #endif
  979.  
  980.             s = LOCK();
  981.             rapMarkBuf(rw, ci, RW_FULL);
  982.  
  983.             /* wake anyone wanted this buffer full  */
  984.             if ( rw->rw_state & RW_WANTED_FULL ) {
  985.  
  986.                 #ifdef DEBUG
  987.                 cmn_err (CE_NOTE, 
  988.                      "rapwrite: Buffer %d is Wanted_Full",
  989.                      rw->rw_idx );
  990.                 #endif
  991.  
  992.                 rw->rw_state &= ~RW_WANTED_FULL;
  993.                 wakeup(rw);
  994.             }
  995.  
  996.             /*
  997.                          *   start DMA if none is going and we filled the 
  998.               *   entire buffers.
  999.              */
  1000.                         if ( (ci->di_state == DI_DMA_IDLE) &&
  1001.                  (rw->rw_idx >= RW_MIN_FULL )  ) {
  1002.  
  1003.                 #ifdef DEBUG
  1004.                 cmn_err (CE_NOTE, 
  1005.                     "rapwrite: Starting Play Dma");
  1006.                 #endif
  1007.  
  1008.                                 err = rapStart(DI_DMA_PLAYING);
  1009.                                 if ( err )   {
  1010.                                    cmn_err (CE_WARN,
  1011.                                    "rapwrite: Could not start playing error %d",                                    err );
  1012.                     UNLOCK(s);
  1013.                                     return(err);
  1014.                                 }
  1015.                         }
  1016.  
  1017.             /*    get next empty buffer  */
  1018.             ci->ri_idx = rapGetNextEmpty(ci->ri_idx, FROM_USR);
  1019.             rw = &rwQue[ci->ri_idx];
  1020.             ci->ri_ptr = rw->rw_buf;
  1021.             UNLOCK(s);
  1022.             continue;
  1023.         }
  1024.  
  1025.         /*  start filling this buffer   */
  1026.         size = (totBytes > avail ? avail: totBytes);
  1027.  
  1028.         err = uiomove (ci->ri_ptr, size, UIO_WRITE, uio);
  1029.         if ( err ) { 
  1030.             cmn_err (CE_NOTE, "rapwrite: uiomov error %d", err);
  1031.             return(err);
  1032.         }
  1033.  
  1034.         rw->rw_count += size;
  1035.         ci->ri_ptr   += size;
  1036.         totBytes = uio->uio_resid;
  1037.  
  1038.         #ifdef DEBUG
  1039.         cmn_err (CE_NOTE, 
  1040.         "rapwrite: Wrote  %d to Buffer %d, Left = %d, rw_count = %d",
  1041.         size, rw->rw_idx, totBytes, rw->rw_count );
  1042.         #endif
  1043.     }
  1044.  
  1045.     return (0);
  1046.  
  1047. } /*** end rapwrite ***/
  1048.  
  1049. /*************************************************************************
  1050.  *            r a p r e a d                 
  1051.  *************************************************************************
  1052.  *
  1053.  *  Name:      rapread
  1054.  *    
  1055.  *  Purpose:   Reads data from rwQue[] into user's buffer.
  1056.  *           This routine waits for current DMA operation to end
  1057.  *           and then starts a A/D Dma (recording). If A/D is already
  1058.  *           going then it simply moves data from current Full buffer
  1059.  *           into user's buffer. If buffer is not full, it waits for
  1060.  *           it to get full. 
  1061.  *
  1062.  *  Returns:   0 = Success, or errno.
  1063.  *
  1064.  *************************************************************************/
  1065. int
  1066. rapread (dev_t  dev, uio_t *uio, cred_t *cred)
  1067. {
  1068.         cardInfo_t    *ci;
  1069.         rwBuf_t       *rw;
  1070.     toid_t        to_id;
  1071.         int           avail, size, totBytes, err, s;
  1072.  
  1073.         ci = &cardInfo;
  1074.  
  1075.     /*===============================*
  1076.      *     Error Checking             *
  1077.      *===============================*/
  1078.  
  1079.     /*  card is not installed */
  1080.         if ( !(ci->ci_state & CARD_INSTALLED) )
  1081.                 return (ENODEV);
  1082.  
  1083.     /*  card is not opened  */
  1084.         if ( !(ci->ci_state & CARD_OPENED) )
  1085.                 return (EACCES);
  1086.  
  1087.     /*  we do not own the card */
  1088.         if ( ci->ci_pid != User_pid )
  1089.                 return (EACCES);
  1090.  
  1091.     /*  card is in middle of a Play operation  */
  1092.     if ( ci->ci_state & CARD_PLAYING ) 
  1093.         return (EIO);   
  1094.  
  1095.     ci->ci_state |= CARD_RECORDING;
  1096.  
  1097.  
  1098.  
  1099.     /*   start a A/D Dma if none is going on  */
  1100.     if ( ci->di_state == DI_DMA_IDLE ) {
  1101.         
  1102.         #ifdef DEBUG
  1103.         cmn_err (CE_NOTE, "rapread: Idle DMA. Starting one");
  1104.         #endif
  1105.  
  1106.         if ( rapStart(DI_DMA_RECORDING) ) {   
  1107.             #ifdef DEBUG
  1108.             cmn_err (CE_NOTE, "rapread: Could not start A/D");
  1109.             #endif
  1110.  
  1111.             ci->ci_state &= ~CARD_RECORDING;
  1112.             UNLOCK(s);
  1113.             return (EIO);
  1114.         }
  1115.     }
  1116.  
  1117.     /*
  1118.      *  get the buffer we should be using and 
  1119.      *  wait for it to become Full
  1120.      */ 
  1121.         rw = &rwQue[ci->ri_idx];
  1122.  
  1123.     #ifdef DEBUG
  1124.         cmn_err (CE_NOTE,
  1125.         "rapread: %d bytes, buf = %d, rw_count = %d, free = %d, full = %d",
  1126.         uio->uio_resid, ci->ri_idx, rw->rw_count, ci->ri_free, ci->ri_full);
  1127.     #endif
  1128.  
  1129.     s = LOCK();
  1130.     if ( !(rw->rw_state & RW_FULL) ) {
  1131.  
  1132.        ci->ri_ptr = NULL;
  1133.        ci->ri_tout = 0;
  1134.        to_id = itimeout (rapTimeOut, rw, RW_TIMEOUT, plbase, 0, 0, 0);
  1135.  
  1136.        while ( !(rw->rw_state & RW_FULL) && !ci->ri_tout ) {
  1137.         
  1138.         #ifdef DEBUG
  1139.         cmn_err (CE_NOTE, "rapread: wating for buf %d to become Full",
  1140.              rw->rw_idx );
  1141.         #endif
  1142.  
  1143.         rw->rw_state |= RW_WANTED_FULL;
  1144.         if ( sleep (rw, PUSER | PCATCH) ) {
  1145.  
  1146.             untimeout (to_id);    
  1147.  
  1148.             #ifdef DEBUG
  1149.             cmn_err (CE_NOTE, "rapread: Interrupted");
  1150.             #endif
  1151.  
  1152.             rw->rw_state &= ~RW_WANTED_FULL;
  1153.             UNLOCK(s);
  1154.             return(EINTR);
  1155.         }
  1156.  
  1157.        } /*  while  */
  1158.  
  1159.        untimeout (to_id);    
  1160.  
  1161.        if ( ci->ri_tout ) {
  1162.         #ifdef DEBUG
  1163.         cmn_err (CE_NOTE, "rapread: Timed out");
  1164.         #endif
  1165.         
  1166.         rw->rw_state &= ~RW_WANTED_FULL;
  1167.         UNLOCK(s);
  1168.         return (EIO);
  1169.        }
  1170.  
  1171.     }  /*  if !rw->rw_state & RW_FULL  */
  1172.  
  1173.     UNLOCK(s);
  1174.  
  1175.  
  1176.     /*    adjust read/write pointer if necessary   */
  1177.     if ( ci->ri_ptr == NULL )
  1178.         ci->ri_ptr = rw->rw_buf;
  1179.  
  1180.     /*===================================*
  1181.       *     Actual Read (Data movement)   *
  1182.      *===================================*/
  1183.         totBytes = uio->uio_resid;
  1184.  
  1185.         while ( totBytes > 0 )  {
  1186.                 avail = rw->rw_count;
  1187.  
  1188.                 /*  if this buffer is Empty, get next Full buffer */
  1189.                 if ( avail <= 0 ) {
  1190.  
  1191.                         #ifdef DEBUG
  1192.                         cmn_err (CE_NOTE, 
  1193.             "rapread: Buffer %d is Empty now, rw_count = %d",
  1194.                                  rw->rw_idx, rw->rw_count );
  1195.                         #endif
  1196.  
  1197.  
  1198.                         s = LOCK();
  1199.                         rapMarkBuf(rw, ci, RW_EMPTY);
  1200.  
  1201.                         /* wake anyone wanted this buffer Empty */
  1202.                         if ( rw->rw_state & RW_WANTED_EMPTY ) {
  1203.  
  1204.                                 #ifdef DEBUG
  1205.                                 cmn_err (CE_NOTE,
  1206.                                          "rapread: Buffer %d is Wanted_Empty",
  1207.                                          rw->rw_idx );
  1208.                                 #endif
  1209.  
  1210.                                 rw->rw_state &= ~RW_WANTED_FULL;
  1211.                                 wakeup(rw);
  1212.             }
  1213.  
  1214.                         /*    get next Full buffer  */
  1215.                         ci->ri_idx = rapGetNextFull(ci->ri_idx, FROM_USR);
  1216.                         rw = &rwQue[ci->ri_idx];
  1217.                         ci->ri_ptr = rw->rw_buf;
  1218.                         UNLOCK(s);
  1219.             continue;
  1220.                 }
  1221.  
  1222.                 /*  start filling this buffer   */
  1223.                 size = (totBytes > avail ? avail: totBytes);
  1224.  
  1225.                 err = uiomove (ci->ri_ptr, size, UIO_READ, uio);
  1226.                 if ( err ) {
  1227.                         cmn_err (CE_PANIC, "rapread: uiomov error %d", err);
  1228.                         return(err);
  1229.                 }
  1230.  
  1231.                 rw->rw_count -= size;
  1232.                 ci->ri_ptr   += size;
  1233.                 totBytes = uio->uio_resid;
  1234.  
  1235.                 #ifdef DEBUG
  1236.                 cmn_err (CE_NOTE, 
  1237.         "rapread: Read %d, Buffer %d, Left = %d, rw_count = %d",
  1238.                  size, rw->rw_idx, totBytes, rw->rw_count );
  1239.                 #endif
  1240.  
  1241.         }
  1242.  
  1243.         return (0);
  1244.  
  1245. }  /***   End rapread    ***/
  1246.  
  1247.  
  1248. /*************************************************************************
  1249.  *            r a p c l o s e              
  1250.  *************************************************************************
  1251.  *
  1252.  *  Name:       rapclose
  1253.  *    
  1254.  *  Purpose:    closes connection to the card and makes it available
  1255.  *        for next process to open it.
  1256.  *
  1257.  *  Returns:    0 = Success, or errno
  1258.  *
  1259.  *************************************************************************/
  1260. int
  1261. rapclose (dev_t dev, int flag, int otyp, cred_t *cred)
  1262. {
  1263.     cardInfo_t    *ci;
  1264.  
  1265.     ci = &cardInfo;
  1266.  
  1267.     #ifdef DEBUG
  1268.     cmn_err (CE_NOTE, 
  1269.     "rapclose: ci_state = %x, di_state = %x, full = %d, empty = %d", 
  1270.          ci->ci_state, ci->di_state, ci->ri_full, ci->ri_free );
  1271.     #endif
  1272.  
  1273.     /*=========================*
  1274.      *    Error Checking     *
  1275.      *=========================*/
  1276.  
  1277.         /*  card is not installed */
  1278.         if ( !(ci->ci_state & CARD_INSTALLED) )
  1279.                 return (ENODEV);
  1280.  
  1281.         /*  card is not opened  */
  1282.         if ( !(ci->ci_state & CARD_OPENED) )
  1283.                 return (EACCES);
  1284.  
  1285.         /*  we do not own the card  */
  1286.         if ( ci->ci_pid != User_pid )
  1287.                 return (EACCES); 
  1288.  
  1289.     return ( rapClose(1) );
  1290. }
  1291.  
  1292.  
  1293. /*************************************************************************
  1294.  *            r a p i n t r                 
  1295.  *************************************************************************
  1296.  *
  1297.  *  Name:       rapintr
  1298.  *    
  1299.  *  Purpose:    Interrupt handling routine
  1300.  *
  1301.  *  Returns:    None.
  1302.  *
  1303.  *************************************************************************/
  1304. void
  1305. rapintr ( int ctl )
  1306. {
  1307.     ushort_t     gpis;
  1308.     uchar_t         dtci;
  1309.     uchar_t         stereo;
  1310.     uchar_t         totreq;
  1311.     uchar_t         playing;
  1312.     uchar_t         moveData;
  1313.     cardInfo_t   *ci;
  1314.     caddr_t         addr;
  1315.  
  1316.     ci = &cardInfo;
  1317.     addr = ci->ci_addr[0];
  1318.  
  1319.     /*
  1320.      *   moveData:  0 = we should move data between Buf/DMA  to DMA/Buf. 
  1321.      *   totreq:    In stereo, we have to wait for 2 BF or BH interrupt
  1322.      *            but in Mono we have to wait for only one.
  1323.      *   playing:   1 = Playing, 0= Recording.
  1324.      */
  1325.     moveData = 0;
  1326.     totreq = (ci->ci_state & CARD_STEREO? 2:1); /* No. of Ints. we need */ 
  1327.     playing = ci->ci_state & CARD_PLAYING; 
  1328.  
  1329.     gpis = INPW(addr+GPIS);
  1330.  
  1331.     /*
  1332.      *    First, check for stray interrupts and ignore them
  1333.      */
  1334.     if ( !(ci->ci_state & (CARD_PLAYING | CARD_RECORDING)) ) {
  1335.         #ifdef DEBUG
  1336.         cmn_err (CE_NOTE, 
  1337.         "rapintr: Stray interupt, gpis = %x, ci_state = %x",
  1338.         ci->ci_state );
  1339.         #endif
  1340.         return;
  1341.     }
  1342.  
  1343.     #ifdef DEBUG
  1344.         cmn_err (CE_NOTE, "rapintr: New ..Gpis = %x", gpis );
  1345.     #endif
  1346.  
  1347.     
  1348.     /**********************************
  1349.      *     DMA Buffers Half/Full      *
  1350.      **********************************/
  1351.     while ( gpis & GPIS_ITC ) {
  1352.  
  1353.         /*   see which buffer is half/full   */
  1354.         dtci = INPB(addr+DTCI);
  1355.  
  1356.         #ifdef DEBUG
  1357.         cmn_err (CE_NOTE, 
  1358.         "rapintr: Dma buffer status..Gpis = %x, Dtci = %x", gpis, dtci);
  1359.         #endif
  1360.  
  1361.         if ( dtci & DTCI_BF0 )
  1362.             ci->di_bf++;
  1363.         if ( dtci & DTCI_BF1 )
  1364.             ci->di_bf++;
  1365.  
  1366.         if (dtci & DTCI_BH0 ) 
  1367.             ci->di_bh++;
  1368.         if (dtci & DTCI_BH1 ) 
  1369.             ci->di_bh++;
  1370.             
  1371.         #ifdef DEBUG
  1372.         cmn_err (CE_NOTE, "rapintr: di_bf = %d, di_bh = %d",
  1373.              ci->di_bf, ci->di_bh );
  1374.         #endif
  1375.  
  1376.         /*  1st half of dma needs service  */
  1377.         if ( ci->di_bh == totreq ) {
  1378.  
  1379.             #ifdef DEBUG
  1380.             cmn_err (CE_NOTE, 
  1381.             "rapintr: DMA First_Half needs service");
  1382.             #endif
  1383.  
  1384.             ci->di_bh    = 0;
  1385.             ci->di_which = 0;  /* 1st half of DMA buffer */
  1386.             moveData     = 1;
  1387.         }
  1388.  
  1389.         /*   2nd half of dma needs service  */
  1390.                 else if ( ci->di_bf == totreq ) {
  1391.  
  1392.                         #ifdef DEBUG
  1393.                         cmn_err (CE_NOTE,  
  1394.                         "rapintr: DMA Second_Half needs service");
  1395.                         #endif
  1396.  
  1397.                         ci->di_bf    = 0;
  1398.             ci->di_which = 1;   /*  2nd half of DMA buffer */
  1399.             moveData     = 1;
  1400.         }
  1401.  
  1402.         /*
  1403.          *   Move data if needed
  1404.          */
  1405.         if ( moveData ) {
  1406.  
  1407.             /*  move data for Play if only data available */
  1408.             if ( playing ) { 
  1409.             
  1410.                 /*  No more data..end of play  */
  1411.                 if ( ci->ri_full <= 0 ) {
  1412.                      if (ci->di_state & DI_DMA_END_PLAY ) {
  1413.                     #ifdef DEBUG
  1414.                     cmn_err (CE_NOTE, 
  1415.                     "rapintr: End of Play Reached");
  1416.                     #endif
  1417.  
  1418.                     if ( ci->ri_state & RI_WANTED_EMPTY ) {
  1419.                        #ifdef DEBUG
  1420.                        cmn_err (CE_NOTE,
  1421.                        "rapintr: Cir.Buff is Wanted Empty");
  1422.                        #endif
  1423.                        ci->ri_state &= ~RI_WANTED_EMPTY;
  1424.                        wakeup (ci);
  1425.                     }
  1426.                     else rapStop(DI_DMA_PLAYING);
  1427.  
  1428.                     return;
  1429.                          }
  1430.                      else {
  1431.                     #ifdef DEBUG
  1432.                     cmn_err (CE_NOTE, 
  1433.                     "rapintr: Playing but no Full buffers");
  1434.                     #endif
  1435.                     return;
  1436.                      }
  1437.  
  1438.                 }
  1439.             
  1440.                 /*  Data is available to play  */
  1441.                 #ifdef DEBUG
  1442.                 cmn_err (CE_NOTE,
  1443.                 "rapintr: Playing..which = %d, idx = %d, full = %d, Empty = %d",
  1444.                 ci->di_which, ci->di_idx, ci->ri_full, ci->ri_free);
  1445.                 #endif
  1446.  
  1447.                 rapBufToDma(DMA_HALF_SIZE);
  1448.  
  1449.             } /* if playing  */
  1450.  
  1451.             else  {   /*  recording  */
  1452.                                 #ifdef DEBUG
  1453.                                 cmn_err (CE_NOTE,
  1454.                                 "rapintr: Recording..which = %d, full = %d, Empty = %d",
  1455.                                 ci->di_which, ci->ri_full, ci->ri_free);
  1456.                                 #endif  
  1457.  
  1458.                                 rapDmaToBuf(DMA_HALF_SIZE);
  1459.                 
  1460.             }
  1461.                 
  1462.         }  /*  if move data  */
  1463.     
  1464.         /*   no need to move data  */
  1465.         else {
  1466.             #ifdef DEBUG
  1467.             cmn_err (CE_NOTE, 
  1468.             "rapintr: Waiting for next interrupt, bf = %d, bh = %d",            ci->di_bf, ci->di_bh);
  1469.             #endif
  1470.         }
  1471.  
  1472.         gpis = INPW(addr+GPIS);
  1473.  
  1474.         #ifdef DEBUG
  1475.         cmn_err (CE_NOTE, "rapintr: next Gpis = %x", gpis);
  1476.         #endif
  1477.  
  1478.     } /* while ( gpis & ..  */
  1479.  
  1480.     #ifdef DEBUG
  1481.     cmn_err (CE_NOTE, "rapintr: finished ...");
  1482.     #endif
  1483.  
  1484. }  /*** End rapintr   ***/
  1485.  
  1486.  
  1487. /*************************************************************************
  1488.  *            r a p i o c t l                
  1489.  *************************************************************************
  1490.  *
  1491.  *  Name:       rapioctl
  1492.  *    
  1493.  *  Purpose:    handles IOCTL calls for RAP-10.
  1494.  *
  1495.  *  Returns:    0 = Success, or errno
  1496.  *
  1497.  *************************************************************************/
  1498. int
  1499. rapioctl (dev_t dev, int cmd, void *arg, int mode, cred_t *cred, int *ret)
  1500. {
  1501.      cardInfo_t    *ci;
  1502.  
  1503.     ci = &cardInfo;
  1504.  
  1505. #ifdef DEBUG
  1506.     cmn_err (CE_NOTE, "rapioctl: Cmd = %d, full = %d, Empty = %d", 
  1507.          cmd, ci->ri_full, ci->ri_free );
  1508. #endif
  1509.  
  1510.         /*
  1511.          *  No card is installed or card is already opened
  1512.          */
  1513.         if ( !(ci->ci_state & CARD_INSTALLED) )
  1514.                 return (ENODEV);
  1515.  
  1516.     if ( !(ci->ci_state & CARD_OPENED) )
  1517.         return (EACCES);
  1518.  
  1519.     if ( ci->ci_pid != User_pid )
  1520.         return (EACCES);
  1521.  
  1522.     *ret = 0;
  1523.  
  1524.     switch ( cmd ) {
  1525.         /*=======================*
  1526.           *   End PLAY            *
  1527.          *=======================*/ 
  1528.         case RAPIOCTL_END_PLAY:
  1529.             if ( !(ci->ci_state & CARD_PLAYING) ) {
  1530.                 #ifdef DEBUG
  1531.                 cmn_err (CE_NOTE, 
  1532.                 "rapioctl: End_PLay command in wrong state");
  1533.                 #endif
  1534.                 return (EACCES);
  1535.             }
  1536.             
  1537.             return (rapClose (0) );
  1538.  
  1539.         /*=======================*
  1540.           *   End RECORD          *
  1541.          *=======================*/ 
  1542.         case RAPIOCTL_END_RECORD:
  1543.                         if ( !(ci->ci_state & CARD_RECORDING) ) {
  1544.                                 #ifdef DEBUG
  1545.                                 cmn_err (CE_NOTE, 
  1546.                                 "rapioctl: End_Recrd command in wrong state");
  1547.                                 #endif
  1548.                                 return (EACCES);
  1549.                         }
  1550.                         
  1551.                         return (rapClose (0) );
  1552.  
  1553.     } /* switch  */
  1554.  
  1555.     return (0);
  1556.  
  1557. } /** End rapioctl  **/
  1558.  
  1559.  
  1560. /****************************************************************************
  1561.  ******            I n t e r n a l   R o u t i n e s             *******
  1562.  ****************************************************************************/
  1563.  
  1564.  
  1565. /*************************************************************************
  1566.  *                      r a p C l o s e
  1567.  *************************************************************************
  1568.  *
  1569.  *  Name:       rapClose
  1570.  *
  1571.  *  Purpose:    Routine to actually ends current operation and releases
  1572.  *              the card. It is written as a separate routine here so
  1573.  *        it can be shared by rapclose() and rapioctl() routines.
  1574.  *        One frees up the card, one does not. Also if we are called
  1575.  *        from ioctl, we will wait till all buffers are played (if 
  1576.  *        in Playback mode).
  1577.  *
  1578.  *  Returns:    0 = Success, or errno
  1579.  *
  1580.  *************************************************************************/
  1581.  
  1582. int
  1583. rapClose( uchar_t relCard )
  1584. {
  1585.  
  1586.         cardInfo_t    *ci;
  1587.         rwBuf_t       *rw;
  1588.         int            s, totLeft;
  1589.  
  1590.         ci = &cardInfo;
  1591.  
  1592.     s = LOCK();
  1593.     rw = &rwQue[ci->ri_idx];
  1594.     
  1595.     #ifdef DEBUG
  1596.     cmn_err (CE_NOTE, 
  1597.     "rapClose: relCard = %d, ci_state = %x, di_state = %x", 
  1598.     relCard, ci->ci_state, ci->di_state );
  1599.     #endif
  1600.  
  1601.  
  1602.     /*
  1603.      *    if we are not recording and are not playing
  1604.      *    then simply mark the card as not opened and return
  1605.      */
  1606.     if ( !(ci->ci_state & (CARD_RECORDING | CARD_PLAYING)) ) {
  1607.         #ifdef DEBUG
  1608.         cmn_err (CE_NOTE, "rapClose: Idle card ..closing");
  1609.         #endif
  1610.     
  1611.         if ( relCard ) {
  1612.             ci->ci_state &= ~CARD_OPENED;
  1613.             ci->ci_pid    = 0;
  1614.         }
  1615.         UNLOCK(s);
  1616.         return(0);
  1617.     }
  1618.     
  1619.     
  1620.     /*
  1621.      *     Recording ? end it. 
  1622.      */
  1623.     if ( ci->ci_state & CARD_RECORDING ) {
  1624.  
  1625.         #ifdef DEBUG
  1626.         cmn_err (CE_NOTE, 
  1627.         "rapClose: Ending Record (A/D)");
  1628.         #endif
  1629.  
  1630.         rapStop(DI_DMA_RECORDING);
  1631.                 if ( relCard ) {
  1632.                         ci->ci_state &= ~CARD_OPENED;
  1633.                         ci->ci_pid    = 0;
  1634.                 }
  1635.                 UNLOCK(s);
  1636.                 return(0);
  1637.     }
  1638.  
  1639.     /*    
  1640.      *    playback and called from close() routine ?
  1641.      *    End the playback 
  1642.      */
  1643.     if ( relCard ) {
  1644.                 #ifdef DEBUG
  1645.                 cmn_err (CE_NOTE,
  1646.                 "rapClose: Ending Playback (D/A");
  1647.                 #endif
  1648.  
  1649.                 rapStop(DI_DMA_PLAYING);   
  1650.                 ci->ci_state &= ~CARD_OPENED;
  1651.                 ci->ci_pid    = 0;
  1652.                 UNLOCK(s);
  1653.                 return(0);
  1654.         }
  1655.  
  1656.     /*
  1657.      *    Called from Ioctl.
  1658.      *    Closing in middle of play is different based on we 
  1659.      *    have been called from close() routine or not.
  1660.      *    If called from Ioctl (relCard = 0), we will wait till
  1661.      *    all buffers are played back.
  1662.      */
  1663.     if ( !(rw->rw_state & RW_FULL) && (rw->rw_count > 0) ) {
  1664.  
  1665.               totLeft = RW_BUF_SIZE - rw->rw_count; 
  1666.  
  1667.               #ifdef DEBUG
  1668.               cmn_err (CE_NOTE,
  1669.               "rapClose: Current Buf %d has %d data. Filled with %d zeros",
  1670.               rw->rw_idx, rw->rw_count, totLeft );
  1671.               #endif
  1672.  
  1673.           if ( totLeft > 0 ) {
  1674.                    bzero (ci->ri_ptr, totLeft);
  1675.          ci->ri_ptr += totLeft;
  1676.           }
  1677.  
  1678.               rapMarkBuf(rw, ci, RW_FULL);
  1679.     }
  1680.  
  1681.     /*   some buffers to play  */
  1682.     if ( ci->ri_full > 0 )     {
  1683.         
  1684.         /*   Playback has not started yet */
  1685.         if ( ci->di_state == DI_DMA_IDLE ) {
  1686.             #ifdef DEBUG
  1687.             cmn_err (CE_NOTE,
  1688.             "rapClose: Starting playback, full = %d, empty = %d",
  1689.             ci->ri_full, ci->ri_free);
  1690.             #endif
  1691.             
  1692.             rapStart(DI_DMA_PLAYING);
  1693.         }
  1694.  
  1695.         ci->di_state  = DI_DMA_IDLE;        
  1696.         ci->di_state |= DI_DMA_END_PLAY;
  1697.  
  1698.         /*  wait till buffers are all played back */        
  1699.         while ( ci->ri_full > 0 ) {
  1700.  
  1701.             #ifdef DEBUG
  1702.             cmn_err (CE_NOTE, 
  1703.             "rapClose: waiting for Play to end..full = %d, empty = %d, ri_idx = %d, di_idx = %d", 
  1704.             ci->ri_full, ci->ri_free, ci->ri_idx, ci->di_idx);
  1705.             #endif
  1706.  
  1707.             ci->ri_state |= RI_WANTED_EMPTY;
  1708.             if ( sleep (ci, PUSER | PCATCH) ) {
  1709.                 #ifdef DEBUG
  1710.                 cmn_err (CE_NOTE, "rapClose: Interrupted");
  1711.                 #endif
  1712.  
  1713.                 rapStop(DI_DMA_PLAYING);
  1714.                     ci->ci_state &= ~CARD_OPENED;
  1715.                     ci->ci_pid    = 0;
  1716.                 UNLOCK(s);
  1717.                 return (EINTR);
  1718.             }
  1719.         }
  1720.         
  1721.         rapStop(DI_DMA_PLAYING);
  1722.  
  1723.     }
  1724.  
  1725.     else {
  1726.         #ifdef DEBUG
  1727.         cmn_err (CE_NOTE, "rapClose: Circular buffer empty..closing");
  1728.         #endif
  1729.  
  1730.         rapStop(DI_DMA_PLAYING);
  1731.     }
  1732.  
  1733.         UNLOCK(s);      
  1734.  
  1735.         return(0);      
  1736.  
  1737. }  /***       End rapClose   ***/
  1738.  
  1739. /*************************************************************************
  1740.  *            r a p S t o p
  1741.  *************************************************************************
  1742.  *
  1743.  *  Name:       rapStop
  1744.  *    
  1745.  *  Purpose:    Stops D/A and A/D conversion.
  1746.  *
  1747.  *  Returns:    None.
  1748.  *
  1749.  *************************************************************************/
  1750. static void
  1751. rapStop( uchar_t what ) 
  1752. {
  1753.     cardInfo_t     *ci;
  1754.     rwBuf_t        *rw;
  1755.     caddr_t           addr;
  1756.     uchar_t        dacm, adcm;
  1757.     ushort_t       gpdi;
  1758.     int           s, i;
  1759.  
  1760.     s = LOCK();
  1761.     
  1762.     ci = &cardInfo;
  1763.     addr = ci->ci_addr[0];
  1764.  
  1765.     gpdi = adcm = dacm = 0;
  1766.  
  1767. #ifdef DEBUG
  1768.     cmn_err (CE_NOTE, 
  1769.         "rapStop:  Stoping %s, full = %d, Empty = %d",
  1770.         (what == DI_DMA_PLAYING ? "Playback(D/A)":"Record(A/D)"),
  1771.         ci->ri_full, ci->ri_free);
  1772. #endif
  1773.  
  1774.     switch ( what ) {
  1775.  
  1776.         /*  stop D/A Conversion (Playing)  */
  1777.         case DI_DMA_PLAYING:
  1778.             ci->di_which = 0;
  1779.             rapZeroDma(ci, DMA_BUF_SIZE);
  1780.             OUTB(addr+DACM, dacm);
  1781.             rapNoteOff (ci);
  1782.             break;
  1783.  
  1784.         /*  stop A/D Conversion (recording) */
  1785.         case DI_DMA_RECORDING:
  1786.             OUTB(addr+ADCM, adcm);
  1787.             OUTB(addr+DACM, dacm);
  1788.             break;
  1789.     }
  1790.  
  1791.     OUTW(addr+GPDI, gpdi);
  1792.     rapReleaseDma(ci);
  1793.         /*   Initialize Card Info structure  */
  1794.     ci->ci_state &= ~(CARD_PLAYING | CARD_RECORDING);
  1795.         ci->ri_idx   = 0;
  1796.         ci->di_idx   = 0;
  1797.         ci->ri_state = 0;
  1798.         ci->di_state = 0;
  1799.         ci->di_ptr   = rwQue[0].rw_buf;
  1800.         ci->ri_ptr   = rwQue[0].rw_buf;
  1801.         ci->ri_free  = RW_BUF_COUNT;
  1802.     ci->ri_full  = 0;
  1803.  
  1804.         /*   Initialize Circular Buffers   */
  1805.         for ( i = 0; i < RW_BUF_COUNT; i++ ) {
  1806.                 rw = &rwQue[i];
  1807.                 rw->rw_count = 0;
  1808.                 rw->rw_state = 0;
  1809.                 rw->rw_idx   = i;
  1810.         bzero (rw->rw_buf, RW_BUF_SIZE);
  1811.         }
  1812.  
  1813.     /*   clear out any hanging GPIS and DACM   */
  1814.     gpdi = INPW(addr+GPIS); 
  1815.  
  1816.     UNLOCK(s);
  1817.  
  1818. } /** End rapStop  **/
  1819.  
  1820.  
  1821.  
  1822. /*************************************************************************
  1823.  *            r a p S t a r t 
  1824.  *************************************************************************
  1825.  *
  1826.  *  Name:       rapStart
  1827.  *    
  1828.  *  Purpose:    Prepares Eisa DMA buffers/Control block for Playing/Recording 
  1829.  *         This function is called when DMA is Idle.    
  1830.  *
  1831.  *  Returns:    0 = Success or Error number. 
  1832.  *
  1833.  *************************************************************************/
  1834.  
  1835. static int 
  1836. rapStart (uchar_t  what) 
  1837. {
  1838.     cardInfo_t   *ci;
  1839.     dmaBuf_t     *dmaB;
  1840.     dmaCb_t      *dmaC;
  1841.     uchar_t      stereo;
  1842.     int         err;
  1843.  
  1844.     ci = &cardInfo;
  1845.     stereo = (ci->ci_state & CARD_STEREO);
  1846.  
  1847. #ifdef DEBUG
  1848.         cmn_err (CE_NOTE,
  1849.                 "rapStart: Starting %s, full = %d, empty = %d",
  1850.                 (what == DI_DMA_PLAYING ? "Playback(D/A)":"Record(A/D)"),
  1851.                 ci->ri_full,  ci->ri_free );
  1852. #endif
  1853.  
  1854.     /*    clear Dma buffers   */
  1855.     ci->di_which = 0;
  1856.     rapZeroDma(ci, DMA_BUF_SIZE);
  1857.     
  1858.     /*   check for Dma buffer addresses  */
  1859.     if ( (ci->ci_dmaBuf5 == (dmaBuf_t *)0) ||
  1860.          (ci->ci_dmaCb5  == (dmaCb_t  *)0) ) {
  1861.         cmn_err (CE_WARN, 
  1862.         "rapStart: Chan 5 dmaBuf/dmaCb is NULL, what = %d", what);
  1863.          return(EIO);
  1864.     }
  1865.     if ( (ci->ci_dmaBuf6 == (dmaBuf_t *)0) ||
  1866.          (ci->ci_dmaCb6  == (dmaCb_t  *)0) ) {
  1867.         cmn_err (CE_WARN, 
  1868.         "rapStart: Chan 6 dmaBuf/dmaCb is NULL, what = %d", what);
  1869.          return(EIO);
  1870.     }
  1871.  
  1872.     /*
  1873.        *     Prepare Eisa Buf and Cb for Channel 5. If in 
  1874.      *    stereo mode, do the same for Channel 6.
  1875.      */
  1876.     dmaB = ci->ci_dmaBuf5;
  1877.     dmaC = ci->ci_dmaCb5;
  1878.  
  1879.     rapPrepEisa (dmaB, dmaC, what, dmaLeftPhys );
  1880.     
  1881.     if ( stereo ) { 
  1882.         dmaB = ci->ci_dmaBuf6;
  1883.         dmaC = ci->ci_dmaCb6;
  1884.         rapPrepEisa (dmaB, dmaC, what, dmaRightPhys );
  1885.     }
  1886.     
  1887.  
  1888.     /*
  1889.      *   Program Eisa DMA Channels
  1890.      */
  1891.         err = eisa_dma_prog (ci->ci_adap, ci->ci_dmaCb5, ci->ci_dmaCh5,
  1892.                            EISA_DMA_NOSLEEP);
  1893.  
  1894.         if ( err == 0 ) { 
  1895.                 cmn_err (CE_WARN, "rapStart: DMA Channel %d is busy",
  1896.                          ci->ci_dmaCh5 );
  1897.                 return (EBUSY);
  1898.         }
  1899.  
  1900.     if ( stereo ) {
  1901.             err = eisa_dma_prog (ci->ci_adap, ci->ci_dmaCb6, ci->ci_dmaCh6,
  1902.                            EISA_DMA_NOSLEEP);
  1903.  
  1904.             if ( err == 0 ) {
  1905.                     cmn_err (CE_WARN, 
  1906.             "rapStart: DMA Channel %d is busy",
  1907.                          ci->ci_dmaCh6 );
  1908.                     return (EBUSY);
  1909.             }
  1910.     }
  1911.  
  1912.  
  1913.     /*   enable hardware recognition on Eisa Dma Channels */
  1914.         eisa_dma_enable (ci->ci_adap, ci->ci_dmaCb5, ci->ci_dmaCh5,
  1915.              EISA_DMA_NOSLEEP);
  1916.  
  1917.     if ( stereo ) {
  1918.             eisa_dma_enable (ci->ci_adap, ci->ci_dmaCb6, ci->ci_dmaCh6,
  1919.                  EISA_DMA_NOSLEEP);
  1920.         
  1921.     }
  1922.  
  1923.     /*  set Eisa DMA register for Autoinit mode  */
  1924.     rapSetAutoInit(ci, what); 
  1925.  
  1926.     ci->di_state |= what; 
  1927.  
  1928.     /*  let's do it ! */
  1929.     if ( what == DI_DMA_PLAYING ) {
  1930.  
  1931.         #ifdef DEBUG
  1932.         cmn_err (CE_NOTE, "rapStart: Starting DMA for D/A Play");
  1933.         #endif
  1934.  
  1935.         rapStartDA();
  1936.     }
  1937.     else {
  1938.                 #ifdef DEBUG
  1939.                 cmn_err (CE_NOTE, "rapStart: Starting DMA for A/D Record");
  1940.                 #endif
  1941.  
  1942.             rapStartAD();
  1943.     }
  1944.  
  1945.     return(0);
  1946.  
  1947. } /**  End rapStart  **/
  1948.  
  1949.  
  1950.  
  1951. /************************************************************************
  1952.  *            r a p P r e p E i s a         
  1953.  *************************************************************************
  1954.  *
  1955.  *  Name:        rapPrepEisa
  1956.  *    
  1957.  *  Purpose:     prepares EISA Buf and Cb structures.
  1958.  *
  1959.  *  Returns:     None.
  1960.  *
  1961.  *************************************************************************/
  1962. static void
  1963. rapPrepEisa( dmaBuf_t *dmaB, dmaCb_t *dmaC, uchar_t  what, paddr_t addr) 
  1964. {
  1965.  
  1966. #ifdef DEBUG
  1967.     cmn_err (CE_NOTE, 
  1968.     "rapPrepEisa: Preparing Eisa DMA buffers for %s",
  1969.     (what == DI_DMA_PLAYING ? "Playback(D/A)" : "Record(A/D)" ) );
  1970. #endif
  1971.  
  1972.     /*   prepare Eisa DMA Buf struct   */
  1973.     bzero (dmaB, sizeof(dmaBuf_t) );
  1974.     dmaB->count = DMA_BUF_SIZE;
  1975.     dmaB->address = addr; 
  1976.     
  1977.     /*  prepare Eisa DMA Control Block  */
  1978.     bzero (dmaC, sizeof(dmaCb_t) );
  1979.  
  1980.     dmaC->reqrbufs   = dmaB;
  1981.     dmaC->reqr_path  = EISA_DMA_PATH_16;
  1982.     dmaC->trans_type = EISA_DMA_TRANS_DMND;
  1983.     dmaC->targ_step  = EISA_DMA_STEP_INC;
  1984.     dmaC->bufprocess = EISA_DMA_BUF_SNGL;    
  1985.  
  1986.     if ( what == DI_DMA_PLAYING ) 
  1987.         dmaC->cb_cmd = EISA_DMA_CMD_READ;   /*  mem -> rap10     */
  1988.     else    dmaC->cb_cmd = EISA_DMA_CMD_WRITE;  /*  rap10 -> mem     */
  1989.  
  1990. } /*** End rapPrepEisa  ***/
  1991.  
  1992.  
  1993. /*************************************************************************
  1994.  *            r a p S t a r t D A 
  1995.  *************************************************************************
  1996.  *
  1997.  *  Name:         rapStartDA 
  1998.  *    
  1999.  *  Purpose:      Enables appropriate RAP interrupts and starts D/A Dma. 
  2000.  *
  2001.  *  Returns:     None
  2002.  *
  2003.  *************************************************************************/
  2004. static void
  2005. rapStartDA()
  2006. {
  2007.         cardInfo_t  *ci;
  2008.         caddr_t     addr;
  2009.         ushort_t    gpdi, gpis, gpst, dtcd, mask;
  2010.         uchar_t     gpcm, pwmd, adcm, dacm;
  2011.         uchar_t     stereo;
  2012.     int        s;
  2013.  
  2014.         ci = &cardInfo;
  2015.         addr = ci->ci_addr[0];
  2016.  
  2017.         stereo = ci->ci_state & CARD_STEREO;
  2018.  
  2019. #ifdef DEBUG
  2020.     cmn_err (CE_NOTE,  
  2021.     "rapStartDA: Starting D/A Dma, full = %d, empty = %d",
  2022.     ci->ri_full, ci->ri_free );
  2023. #endif
  2024.         /*
  2025.          *  Prepare the board for Record (A/D)
  2026.          *  Here is what we will do (in exact order):
  2027.          *
  2028.          *   GPDI:  Stereo = 0xA800, Mono = 0x9800
  2029.          *          itc = 1, dma transfer match count
  2030.          *          Stereo:   Drq1->Dma5, Drq0->Dma6
  2031.          *          Mono:     Drq1->Dma5
  2032.      *        Dt1, Dt0 = 10, Chan 1 ->Drq1, Chan 0 ->Drq0
  2033.          *          Left Chan->Drq1, Right Chan->Drq0
  2034.          *
  2035.          *
  2036.          *   DACM:  Stereo: BF, Mono: BE 
  2037.          *          scc = 1, Dma size in byte
  2038.          *          ts1 = ts2 = 1, transfer size of 4096 bytes
  2039.      *        dl1 = dl0 = 1; Data length of 16 bits for both Channels.
  2040.      *          Stereo ? ds1 = ds0 = 1  Start D/A on both Channels. 
  2041.      *        Mono   ? ds1 = 1        Start D/A on Channel 1
  2042.      *
  2043.          *   GPCM:   Select Mike level = 0x04
  2044.          *                   Aux  level = 0x08
  2045.          *   PWMD:   0xFF (Max level)
  2046.          */
  2047.  
  2048.         gpdi = (stereo ? 0xA800: 0x9800);
  2049.     dacm = (stereo ? 0xBF:0xBE);
  2050.     gpcm = 0x04;
  2051.     pwmd = 0xFF;
  2052.     mask = (stereo ? (GPIS_DN1|GPIS_DN0): GPIS_DN1);
  2053.  
  2054.     #ifdef DEBUG
  2055.     cmn_err (CE_NOTE, 
  2056.     "rapStartDA: gpdi = %x, dacm = %x", gpdi, dacm);
  2057.     #endif
  2058.  
  2059.     /*  Set Rap-10 card   */ 
  2060.     OUTB(addr+GPCM, gpcm);
  2061.     OUTB(addr+PWMD, pwmd);
  2062.     OUTW(addr+GPDI, gpdi);
  2063.     OUTB(addr+DACM, dacm);
  2064.  
  2065.     /*
  2066.      *  Busy-wait for both Note_On interrupts
  2067.      *  The interrupt version is commenetd out for now.
  2068.      */ 
  2069.     gpis = INPW(addr+GPIS);
  2070.  
  2071.         #ifdef DEBUG
  2072.         cmn_err (CE_NOTE, 
  2073.     "rapStartDA: Waiting for Note_On, gpis = %x, mask = %x",
  2074.                  gpis, mask);
  2075.         #endif
  2076.  
  2077.         while ( !(gpis & mask) ) {
  2078.                 gpis = INPW(addr+GPIS);
  2079.  
  2080.                 #ifdef DEBUG
  2081.                 cmn_err (CE_NOTE, "rapStartDA: Waiting ..new gpis = %x", gpis);
  2082.                 #endif
  2083.         }
  2084.  
  2085.     #ifdef DEBUG
  2086.     cmn_err (CE_NOTE, "rapStartDA:  Note_On Interrupt Received, gpis = %x",
  2087.     gpis );
  2088.     #endif
  2089.  
  2090.     rapNoteOn(ci, gpis);
  2091.  
  2092. }  /***   End rapStartDA   ***/
  2093.  
  2094.  
  2095.  
  2096. /*************************************************************************
  2097.  *                      r a p S t a r t A D
  2098.  *************************************************************************
  2099.  *
  2100.  *  Name:         rapStartAD
  2101.  *
  2102.  *  Purpose:      Enables appropriate RAP interrupts and starts A/D Dma.
  2103.  *
  2104.  *  Returns:     None
  2105.  *
  2106.  *************************************************************************/
  2107. static void
  2108. rapStartAD()
  2109. {
  2110.         cardInfo_t  *ci;
  2111.         caddr_t     addr;
  2112.         ushort_t    gpdi; 
  2113.         uchar_t     gpcm, pwmd, adcm, dacm;
  2114.     uchar_t        stereo, mic;
  2115.  
  2116.         ci = &cardInfo;
  2117.         addr = ci->ci_addr[0];
  2118.  
  2119.     stereo = ci->ci_state & CARD_STEREO;
  2120.  
  2121. #ifdef DEBUG
  2122.         cmn_err (CE_NOTE,  
  2123.         "rapStartAD: Starting A/D Dma in %s, full = %d, empty = %d",
  2124.         (stereo ? "Stereo":"Mono"), ci->ri_full, ci->ri_free );
  2125. #endif
  2126.  
  2127.     /*
  2128.      *  Prepare the board for Record (A/D)
  2129.      *  Here is what we will do (in exact order):
  2130.          *
  2131.          *   GPDI:  Stereo = 0xA400, Mono = 0x9400
  2132.          *          itc = 1, dma transfer match count
  2133.          *          Stereo:   Drq1->Dma5, Drq0->Dma6
  2134.          *          Mono:     Drq1->Dma5
  2135.      *        Dt1, Dt0 = 01, Left Chan->Drq1, Right Chan->Drq0
  2136.          *
  2137.          *
  2138.          *   DACM:  0xB0
  2139.          *          scc = 1, Dma size in byte
  2140.          *          ts1 = ts2 = 1, transfer size of 4096 bytes
  2141.          *
  2142.          *
  2143.          *   GPCM:   Select Mic level = 0x04
  2144.          *                  Aux level = 0x08
  2145.          *   PWMD:   0xFF (Max level)
  2146.          *
  2147.          *
  2148.          *   ADCM:  Stereo: Mic 0x6F, line 0x4F,
  2149.          *          Mono:   Mic 0x6D, line 0x4D
  2150.          *            Mon = 1, Monitor ON
  2151.          *            Gin = 1, Head Amp Gain to Mic.
  2152.          *            Af1, Af0 = 01, 22.05 KHz
  2153.          *            Adl = 1, 16 bit data length
  2154.          *            Stereo,  Adm = 1, else = 0
  2155.          *            Ads = 1, Start A/D
  2156.          */
  2157.  
  2158.     gpdi = (stereo ? 0xA400: 0x9400);
  2159.     gpcm = 0x08;
  2160.     adcm = (stereo ? 0x6F:0x6D);
  2161.     dacm = 0xB0;
  2162.       gpcm = 0x04;
  2163.     pwmd = 0xFF;    
  2164.  
  2165.     #ifdef DEBUG
  2166.     cmn_err (CE_NOTE,     
  2167.     "rapStartAD: Rap init as: gpdi = %x, dacm = %x, gpcm = %x, adcm = %x",
  2168.     gpdi, dacm, gpcm, adcm);
  2169.     #endif
  2170.  
  2171.     OUTW(addr+GPDI, gpdi);    
  2172.     OUTB(addr+DACM, dacm);                             
  2173.     OUTB(addr+GPCM, gpcm);    
  2174.     OUTB(addr+PWMD, pwmd);   
  2175.     OUTB(addr+ADCM, adcm);    
  2176.  
  2177. }  /***  End rapStartAD  ***/
  2178.  
  2179.  
  2180. /*************************************************************************
  2181.  *            r a p B u f T o D m a         
  2182.  *************************************************************************
  2183.  *
  2184.  *  Name:       rapBufToDma
  2185.  *    
  2186.  *  Purpose:    moves data from current rwQue[] entry to DMA buffers.
  2187.  *        This routine is called by INterrupt handler only except 
  2188.  *        once before we startd D/A (when no DMA is programmed yet)
  2189.  *
  2190.  *  Returns:    None
  2191.  *
  2192.  *************************************************************************/
  2193. static void
  2194. rapBufToDma( int  bytes)
  2195. {
  2196.     cardInfo_t    *ci;
  2197.     rwBuf_t       *rw;
  2198.     uchar_t       *dmaR;
  2199.     uchar_t          *dmaL;
  2200.     uchar_t          stereo;
  2201.     int          i, j, s;
  2202.     
  2203.     ci = &cardInfo;
  2204.     rw = &rwQue[ci->di_idx];
  2205.     stereo = ci->ci_state & CARD_STEREO;
  2206.  
  2207.         /*
  2208.          *      filling 1st half or 2nd half of the buffers ?
  2209.          */
  2210.         if ( ci->di_which ) {
  2211.                dmaR = &dmaRight[DMA_HALF_SIZE];
  2212.                dmaL = &dmaLeft[DMA_HALF_SIZE];
  2213.                if ( bytes == DMA_BUF_SIZE ) {
  2214.                     bytes = DMA_HALF_SIZE;
  2215.                }
  2216.         }
  2217.         /*  filling 1st half of dma buffers */
  2218.         else {
  2219.             dmaR = &dmaRight[0];
  2220.             dmaL = &dmaLeft[0];
  2221.         }
  2222.  
  2223.  
  2224. #ifdef DEBUG
  2225.     cmn_err (CE_NOTE, 
  2226.     "rapBufToDma: Bytes = %d, which = %d, Idx = %d, rw_count = %d, Full = %d, Empty = %d",
  2227.     bytes, ci->di_which, ci->di_idx, rw->rw_count, ci->ri_full, 
  2228.     ci->ri_free);
  2229. #endif
  2230.  
  2231.     /*
  2232.      *   if buffer is not Full, we zero out dma buffers and 
  2233.      *   return. We cannot wait till it gets Full.
  2234.      */
  2235.     if ( !(rw->rw_state & RW_FULL) ) {
  2236.  
  2237.         rapZeroDma(ci, bytes);
  2238.         ci->di_ptr = NULL;
  2239.  
  2240.                 #ifdef DEBUG
  2241.                 cmn_err (CE_NOTE,
  2242.                 "rapBufToDma: Buf %d is not Full, rw_state = %x",
  2243.         rw->rw_idx, rw->rw_state ); 
  2244.         #endif
  2245.  
  2246.         return;
  2247.     }
  2248.  
  2249.     /*  buffer is full of data ..readjust the buffer pointer */
  2250.     if ( ci->di_ptr == NULL ) 
  2251.         ci->di_ptr = rw->rw_buf;
  2252.  
  2253.     /*
  2254.      *    Fill buffers ...
  2255.      */
  2256.     for ( i = 0; i < bytes; i++ ) {
  2257.  
  2258.                 /*
  2259.                  *  First check if buffer is empty. If it is, mark it 
  2260.                  *  as empty, wake anyone up who wants it and get the 
  2261.                  *  next full buffer.
  2262.                  */
  2263.                 if ( rw->rw_count <= 0 ) { 
  2264.  
  2265.                         #ifdef DEBUG
  2266.                         cmn_err (CE_NOTE,
  2267.                         "rapBufToDma: Buf %d is Empty now, rw_count = %d",
  2268.              rw->rw_idx, rw->rw_count );
  2269.                         #endif
  2270.  
  2271.                         rapMarkBuf(rw, ci, RW_EMPTY);
  2272.             ci->di_ptr = NULL;
  2273.  
  2274.                         if ( rw->rw_state & RW_WANTED_EMPTY ) {
  2275.  
  2276.                                 #ifdef DEBUG
  2277.                                 cmn_err (CE_NOTE,
  2278.                                 "rapBufToDma: Buf %d is Wanted_Empty",
  2279.                                 rw->rw_idx );
  2280.                                 #endif
  2281.  
  2282.                                 rw->rw_state &= ~RW_WANTED_EMPTY;
  2283.                                 wakeup(rw);
  2284.                         }
  2285.  
  2286.                         j = rapGetNextFull (ci->di_idx, FROM_INTR);
  2287.                         if ( j == -1 ) {
  2288.                                 #ifdef DEBUG
  2289.                                 cmn_err (CE_NOTE,
  2290.                                 "rapBufToDma: Could not get next Full buffer");
  2291.                                 #endif
  2292.  
  2293.                                 break;
  2294.                         }
  2295.  
  2296.                         ci->di_idx = j;
  2297.                         rw = &rwQue[ci->di_idx];
  2298.                         ci->di_ptr = rw->rw_buf;
  2299.             continue;
  2300.                 }
  2301.  
  2302.         /*  buffer still has some data ..move them  */
  2303.         if ( stereo ) {
  2304.                         dmaL[i] = *(ci->di_ptr++);
  2305.                         dmaR[i] = *(ci->di_ptr++);
  2306.             rw->rw_count -= 2;
  2307.         }
  2308.         else {    
  2309.             dmaL[i] = *(ci->di_ptr++);
  2310.             rw->rw_count--;
  2311.         }
  2312.     
  2313.             
  2314.     } /* for .. */ 
  2315.  
  2316.     /*  Flush the cache line so that Dma buffers contain all data */
  2317.         dki_dcache_wbinval (dmaL, (unsigned)bytes);
  2318.     if ( stereo ) 
  2319.             dki_dcache_wbinval (dmaR, (unsigned)bytes);
  2320.  
  2321. }  /*** end rapBufToDma  ***/
  2322.  
  2323.  
  2324. /*************************************************************************
  2325.  *                      r a p D m a T o B u f 
  2326.  *************************************************************************
  2327.  *
  2328.  *  Name:       rapDmaToBuf
  2329.  *
  2330.  *  Purpose:    Moves data from DMA buffers (Right and Left in stereo)
  2331.  *        into a rwQue entry.  This routine is called only by
  2332.  *        Interrupt Handler.
  2333.  *
  2334.  *  Returns:    None
  2335.  *
  2336.  *************************************************************************/
  2337. static void
  2338. rapDmaToBuf( int  bytes) 
  2339. {
  2340.         cardInfo_t    *ci;
  2341.         rwBuf_t       *rw;
  2342.         uchar_t       *dmaR;
  2343.         uchar_t       *dmaL;
  2344.         uchar_t       stereo;
  2345.         int           i, j, s, inc;
  2346.  
  2347.         ci = &cardInfo;
  2348.         rw = &rwQue[ci->di_idx];
  2349.         stereo = ci->ci_state & CARD_STEREO;
  2350.  
  2351.         /*
  2352.          *      filling 1st half or 2nd half of the buffers ?
  2353.          */
  2354.         if ( ci->di_which ) {
  2355.                dmaR = &dmaRight[DMA_HALF_SIZE];
  2356.                dmaL = &dmaLeft[DMA_HALF_SIZE];
  2357.                if ( bytes == DMA_BUF_SIZE ) {
  2358.                     bytes = DMA_HALF_SIZE;
  2359.                }
  2360.         }
  2361.         /*  filling 1st half of dma buffers */
  2362.         else {
  2363.             dmaR = &dmaRight[0];
  2364.             dmaL = &dmaLeft[0];
  2365.         }
  2366.  
  2367.     /*   Invalidate the Cache    */
  2368.     dki_dcache_inval (dmaL, (unsigned)bytes);
  2369.     if ( stereo ) 
  2370.         dki_dcache_inval (dmaR, (unsigned)bytes);
  2371.  
  2372.     #ifdef DEBUG
  2373.         cmn_err (CE_NOTE,
  2374.         "rapDmaToBuf: Bytes= %d, Idx = %d, rw_count = %d, Full = %d, Empty= %d",
  2375.         bytes, ci->di_idx, rw->rw_count, ci->ri_full, ci->ri_free);
  2376.     #endif
  2377.  
  2378.  
  2379.         /*
  2380.          *  if buffer is Full ..we cannot wait ! Ignore new data
  2381.       *  by simply returning.
  2382.          */
  2383.     if ( rw->rw_state & RW_FULL ) {
  2384.  
  2385.                 #ifdef DEBUG
  2386.                 cmn_err (CE_NOTE,
  2387.                 "rapDmaToBuf: Buf %d is not Empty ..Ignoring data", 
  2388.                 rw->rw_idx );
  2389.                 #endif
  2390.  
  2391.         return;
  2392.     }
  2393.  
  2394.     /*  buffer is Empty ..calculate the end address */
  2395.         if ( ci->di_ptr == NULL )
  2396.                 ci->di_ptr = rw->rw_buf;
  2397.  
  2398.     #ifdef DEBUG
  2399.         cmn_err (CE_NOTE, 
  2400.      "rapDmaToBuf: Moving %s of DMA buffers in %s, rw_count = %x", 
  2401.         (ci->di_which ? "Second Half" : "First Half"),
  2402.     (stereo ? "Stereo":"Monoe"), rw->rw_count);
  2403.     #endif
  2404.  
  2405.         /*
  2406.          *      Fill buffers ...in stereo bytes are Left:Right:Left:Right...
  2407.          */
  2408.     
  2409.            for ( i = 0; i < bytes; i++ ) {
  2410.  
  2411.                 /*
  2412.                  *  First check if this buffer is Full or not.    
  2413.                  *  If it is, mark it as Full and wake anyone up who is
  2414.                  *  waiting for it. Then get the next Empty buffer.
  2415.                  */
  2416.                 if ( rw->rw_count >= RW_BUF_SIZE ) {
  2417.  
  2418.                         #ifdef DEBUG
  2419.                         cmn_err (CE_NOTE,
  2420.                         "rapDmaToBuf: Buf %d is Full now, rw_count = %d",
  2421.                         rw->rw_idx, rw->rw_count );
  2422.                         #endif
  2423.  
  2424.                         rapMarkBuf(rw, ci, RW_FULL);
  2425.  
  2426.                         if ( rw->rw_state & RW_WANTED_FULL ) {
  2427.  
  2428.                                 #ifdef DEBUG
  2429.                                 cmn_err (CE_NOTE,
  2430.                                 "rapDmaToBuf: Buf %d is Wanted_Full",
  2431.                                 rw->rw_idx );
  2432.                                 #endif
  2433.  
  2434.                                 rw->rw_state &= ~RW_WANTED_FULL;
  2435.                                 wakeup(rw);
  2436.                         }
  2437.  
  2438.                         j = rapGetNextEmpty(ci->di_idx, FROM_INTR);
  2439.                         if ( j == -1 ) {
  2440.                                 cmn_err (CE_NOTE,
  2441.                                       "rapDmaToBuf: Could not get next empty");
  2442.                                 return;
  2443.                         }
  2444.                         ci->di_idx = j;
  2445.                         rw = &rwQue[ci->di_idx];
  2446.                         ci->di_ptr = rw->rw_buf;
  2447.             continue;
  2448.                 }
  2449.  
  2450.         /*  buffer still has room ...move data  */
  2451.         if ( stereo ) {
  2452.             *(ci->di_ptr++) = dmaL[i];
  2453.             *(ci->di_ptr++) = dmaR[i];
  2454.             rw->rw_count     += 2;
  2455.  
  2456.         }
  2457.  
  2458.                 else { 
  2459.             *(ci->di_ptr++) = dmaL[i];
  2460.             rw->rw_count++;
  2461.                 }
  2462.  
  2463.         } /* while bytes ... */
  2464.  
  2465. }  /*** end rapDmaToBuf  ***/
  2466.  
  2467.  
  2468.  
  2469.  
  2470. /*************************************************************************
  2471.  *                      r a p G e t N e x t F u l l  
  2472.  *************************************************************************
  2473.  *
  2474.  *  Name:        rapGetNextFull
  2475.  *
  2476.  *  Purpose:     returns the index of next Full  entry in rwQue[],
  2477.  *               starting from a given index. Sleeps if the entry
  2478.  *               is not Full. 
  2479.  *
  2480.  *  Returns:     the index of the empty entry.
  2481.  *
  2482.  *************************************************************************/
  2483. static short 
  2484. rapGetNextFull (short idx, uchar_t fromIntr)
  2485. {
  2486.     cardInfo_t  *ci;
  2487.         int          s;
  2488.     toid_t       to_id;
  2489.         rwBuf_t      *rw;
  2490.  
  2491.     ci = &cardInfo;
  2492.  
  2493. #ifdef DEBUG
  2494.     cmn_err (CE_NOTE, 
  2495.     "rapGetNextFull: Getting Next Full Buffer..idx = %d, fromIntr: %d", 
  2496.     idx, fromIntr );
  2497. #endif
  2498.  
  2499.         /*  go to beginning if at the end of the queu  */
  2500.         idx++;
  2501.         if ( idx >= RW_BUF_COUNT )
  2502.                 idx = 0;
  2503.  
  2504.  
  2505.         rw = &rwQue[idx];
  2506.  
  2507.         /*
  2508.          *    if buffer is not available and we were called from Intrupt
  2509.          *    handler, simply ignore the request and return error
  2510.          */
  2511.     s = LOCK();
  2512.         if ( !(rw->rw_state & RW_FULL) && (fromIntr) ) {
  2513.                 #ifdef DEBUG
  2514.                 cmn_err (CE_NOTE,
  2515.                 "rapGetNextFull: Buffer %d is not Full. ..Cannot Wait",
  2516.                 rw->rw_idx);
  2517.                 #endif
  2518.  
  2519.         UNLOCK(s);
  2520.                 return(-1);
  2521.         }       
  2522.  
  2523.     /*   wait for the buffer to become Full  */
  2524.     if ( !(rw->rw_state & RW_FULL) ) {
  2525.  
  2526.        ci->ri_tout = 0;
  2527.        to_id = itimeout (rapTimeOut, rw, RW_TIMEOUT, plbase, 0, 0, 0);
  2528.            while ( !(rw->rw_state & RW_FULL) && !ci->ri_tout ) {
  2529.  
  2530.         #ifdef DEBUG
  2531.         cmn_err (CE_NOTE, 
  2532.         "rapGetNextFull:  Waiting for Buf %d to become Full", 
  2533.         rw->rw_idx );
  2534.         #endif
  2535.  
  2536.                 rw->rw_state |= RW_WANTED_FULL; 
  2537.                 if ( sleep(rw, PUSER | PCATCH) ) {
  2538.  
  2539.             untimeout(to_id);
  2540.  
  2541.                         #ifdef DEBUG
  2542.                         cmn_err (CE_NOTE, "rapGetNextFull: Interrupted");
  2543.                         #endif
  2544.  
  2545.                         rw->rw_state &= ~RW_WANTED_FULL;
  2546.                         UNLOCK(s);
  2547.                         return(-1);    
  2548.                 }
  2549.  
  2550.            }
  2551.            untimeout (to_id);
  2552.  
  2553.            if ( ci->ri_tout ) {
  2554.                 #ifdef DEBUG
  2555.                 cmn_err (CE_NOTE, "raGetNextFull: Timed out");
  2556.                 #endif
  2557.  
  2558.                 rw->rw_state &= ~RW_WANTED_FULL;
  2559.                 UNLOCK(s);
  2560.                 return (-1);  
  2561.            }
  2562.  
  2563.  
  2564.     }  /*  if !(rw->rw_state & RW_FULL)  */
  2565.  
  2566.         UNLOCK(s);
  2567.  
  2568.     #ifdef DEBUG
  2569.     cmn_err (CE_NOTE, "rapGetNextFull: next Full Buffer is %d", idx);
  2570.     #endif
  2571.  
  2572.         return(idx);
  2573.  
  2574.  
  2575. }  /***   End rapGetNextFull   ***/
  2576.  
  2577.  
  2578.  
  2579. /*************************************************************************
  2580.  *            r a p G e t N e x t E m p t y 
  2581.  *************************************************************************
  2582.  *
  2583.  *  Name:        rapGetNextEmpty
  2584.  *    
  2585.  *  Purpose:     returns the index of next empty entry in rwQue[],
  2586.  *         starting from a given index. Sleeps if the entry
  2587.  *         is not empty. 
  2588.  *
  2589.  *  Returns:     the index of the empty entry.
  2590.  *
  2591.  *************************************************************************/
  2592. static short  
  2593. rapGetNextEmpty (short idx, uchar_t fromIntr)
  2594. {
  2595.     cardInfo_t  *ci;
  2596.     int         s;
  2597.     toid_t       to_id;
  2598.     rwBuf_t     *rw;
  2599.  
  2600.  
  2601.     ci = &cardInfo;
  2602.  
  2603. #ifdef DEBUG
  2604.         cmn_err (CE_NOTE,
  2605.         "rapGetNextEmpty: Getting Next Empty Buffer..idx = %d, fromIntr: %d", 
  2606.     idx, fromIntr );
  2607. #endif
  2608.  
  2609.     /*  go to beginning if at the end of the queu  */
  2610.     idx++;
  2611.     if ( idx >= RW_BUF_COUNT )
  2612.         idx = 0;
  2613.  
  2614.  
  2615.     rw = &rwQue[idx];
  2616.     s = LOCK();
  2617.  
  2618.     /*
  2619.      *    if buffer is nit available and we were called from Intrupt
  2620.      *    handler, simply ignore the request and return error
  2621.      */
  2622.     if ( (rw->rw_state & RW_FULL) && (fromIntr) ) {
  2623.                 #ifdef DEBUG
  2624.                 cmn_err (CE_NOTE,
  2625.                 "rapGetNextEmpty: Buffer %d is not Empty ..Cannot Wait",
  2626.                 rw->rw_idx);
  2627.                 #endif
  2628.  
  2629.         UNLOCK(s);
  2630.                 return(-1);
  2631.     }
  2632.  
  2633.     /*   wait for the buffer to become Empty   */
  2634.     if ( rw->rw_state & RW_FULL ) {
  2635.  
  2636.        ci->ri_tout = 0;
  2637.            to_id = itimeout (rapTimeOut, rw, RW_TIMEOUT, plbase, 0, 0, 0);
  2638.  
  2639.        while ( (rw->rw_state &  RW_FULL) && !ci->ri_tout ) {
  2640.  
  2641.                 #ifdef DEBUG
  2642.                 cmn_err (CE_NOTE,
  2643.                 "rapGetNextEmpty: Waiting for Buf %d to become Empty",
  2644.                 rw->rw_idx );
  2645.                 #endif
  2646.  
  2647.         rw->rw_state |= RW_WANTED_EMPTY;
  2648.                 if ( sleep(rw, PUSER | PCATCH) ) {
  2649.  
  2650.             untimeout(to_id);
  2651.  
  2652.                         #ifdef DEBUG
  2653.                         cmn_err (CE_NOTE, "rapGetNextEmpty: Interrupted");
  2654.                         #endif
  2655.  
  2656.                         rw->rw_state &= ~RW_WANTED_EMPTY;
  2657.                         UNLOCK(s);
  2658.                         return(-1);
  2659.                 }
  2660.  
  2661.        }  /*  while .. */ 
  2662.  
  2663.            untimeout (to_id);
  2664.  
  2665.            if ( ci->ri_tout ) {
  2666.                 #ifdef DEBUG
  2667.                 cmn_err (CE_NOTE, "raGetNextEmpty: Timed out");
  2668.                 #endif
  2669.  
  2670.                 rw->rw_state &= ~RW_WANTED_EMPTY;
  2671.                 UNLOCK(s);
  2672.                 return (-1);
  2673.            }
  2674.  
  2675.  
  2676.     }  /*  if (rw->rw_state & RW_FULL) */
  2677.  
  2678.     UNLOCK(s);
  2679.  
  2680.         #ifdef DEBUG
  2681.         cmn_err (CE_NOTE, "rapGetNextEmpty: next Empty Buffer is %d", idx);
  2682.         #endif
  2683.  
  2684.     return(idx);
  2685.  
  2686. }  /***    End rapGetNextEmpty   ***/
  2687.  
  2688.     
  2689. /*************************************************************************
  2690.  *            r a p D i s I n t             
  2691.  *************************************************************************
  2692.  *
  2693.  *  Name:        rapDisInt
  2694.  *    
  2695.  *  Purpose:     Disables RAP-10 interrupts. 
  2696.  *
  2697.  *  Returns:     None.
  2698.  *
  2699.  *************************************************************************/
  2700. static void
  2701. rapDisInt( cardInfo_t   *ci)
  2702. {
  2703.     caddr_t    addr;
  2704.     ushort_t   s;   
  2705.     uchar_t    c;
  2706.  
  2707. #ifdef DEBUG
  2708.     cmn_err (CE_NOTE, "rapDisInt: full = %d, empty = %d, di_state = %d",
  2709.     ci->ri_full, ci->ri_free, ci->di_state );
  2710. #endif
  2711.  
  2712.     addr = ci->ci_addr[0];
  2713.  
  2714.     /*   disable all Interrupts   */
  2715.     s = 0;    
  2716.     OUTW(addr+GPDI, s);     
  2717.     OUTB(addr+DACM, 0x00);
  2718.     OUTB(addr+ADCM, 0x00);
  2719.     #ifdef DEBUG
  2720.     cmn_err (CE_NOTE, "rapDisInt: Rap is set");       
  2721.     #endif
  2722.  
  2723. } /*** End rapDisInt  ***/
  2724.  
  2725.  
  2726. /**************************************************************************
  2727.  *                         r a p G e t D m a                              *
  2728.  **************************************************************************
  2729.  *
  2730.  *     Name:       rapGetDma
  2731.  *
  2732.  *     Purpose:    allocates dma Buf and Cb structures
  2733.  *
  2734.  *     Returns:    0 = Success,  1 = Error
  2735.  *
  2736.  **************************************************************************/
  2737.  
  2738. static int
  2739. rapGetDma ( dmaBuf_t  **dmaB,  dmaCb_t  **dmaC, int ch )
  2740. {
  2741.  
  2742. #ifdef DEBUG
  2743.     cmn_err (CE_NOTE, 
  2744.     "rapGetDma: Getting Eisa Dma Buf and Cb for Channel %d", ch); 
  2745. #endif
  2746.  
  2747.         *dmaB = eisa_dma_get_buf (EISA_DMA_SLEEP);
  2748.         if ( *dmaB == NULL )
  2749.                 return (1);
  2750.  
  2751.         *dmaC = eisa_dma_get_cb ( EISA_DMA_SLEEP );
  2752.         if ( *dmaC == NULL )
  2753.                 return (1);
  2754.  
  2755.         return (0);
  2756.  
  2757. } /***  End rapGetDma   ***/
  2758.  
  2759.  
  2760.     
  2761. /*************************************************************************
  2762.  *            r a p M a r k B u f         
  2763.  *************************************************************************
  2764.  *
  2765.  *  Name:       rapMarkBuf
  2766.  *    
  2767.  *  Purpose:    Marks a buffer (Empty, Busy, Full) and increments/decrements
  2768.  *        appropriate counters. Buffers status changed as:
  2769.  *            Empty -> Busy -> Full -> Empty -> Busy .. 
  2770.  *
  2771.  *  Returns:    None.
  2772.  *
  2773.  *************************************************************************/
  2774. static void
  2775. rapMarkBuf (rwBuf_t  *rw, cardInfo_t  *ci, uchar_t  m)
  2776. {
  2777.     int    s;
  2778.  
  2779.     s = LOCK();
  2780.  
  2781.     switch ( m ) {
  2782.         case RW_EMPTY:
  2783.  
  2784.             rw->rw_state &= ~RW_FULL; 
  2785.  
  2786.             if ( ci->ri_full )
  2787.                 ci->ri_full--;
  2788.  
  2789.             ci->ri_free++;
  2790.             rw->rw_count = 0;
  2791.             
  2792.             #ifdef DEBUG
  2793.             cmn_err (CE_NOTE, 
  2794.             "rapMarkBuf: Buf %d set EMPTY. Full = %d, Emp = %d",
  2795.             rw->rw_idx, ci->ri_full, ci->ri_free );
  2796.             #endif
  2797.  
  2798.             break;
  2799.  
  2800.         case RW_FULL:
  2801.  
  2802.             rw->rw_state |= RW_FULL;
  2803.             ci->ri_full++;
  2804.             if ( ci->ri_free ) 
  2805.                ci->ri_free--;
  2806.             rw->rw_count = RW_BUF_SIZE;
  2807.  
  2808.                         #ifdef DEBUG
  2809.                         cmn_err (CE_NOTE, 
  2810.                         "rapMarkBuf: Buf %d set FULL. Full = %d, Emp = %d",
  2811.                         rw->rw_idx, ci->ri_full, ci->ri_free );
  2812.             #endif
  2813.  
  2814.             break;
  2815.     }
  2816.  
  2817.     UNLOCK(s);
  2818.  
  2819. }  /***   End rapMarkBuf   ***/
  2820.  
  2821.  
  2822. /*************************************************************************
  2823.  *            r a p K e r n M e m            
  2824.  *************************************************************************
  2825.  *
  2826.  *  Name:       rapKernMem
  2827.  *    
  2828.  *  Purpose:    Allocates/Disallocates Kernel memory for Right and
  2829.  *        Left DMA channels.
  2830.  *
  2831.  *  Returns:    0 = Success,  1 = Failure.
  2832.  *
  2833.  *************************************************************************/
  2834. static int
  2835. rapKernMem ( uchar_t what)
  2836. {
  2837.  
  2838. #ifdef DEBUG
  2839.     cmn_err (CE_NOTE, "rapKernMem: %s Kernel Contigious Memory",
  2840.          (what == 1 ? "Allocating" : "Deallocating") );
  2841. #endif
  2842.  
  2843.     switch ( what ) {
  2844.  
  2845.         /*=======================================*
  2846.          *     Allocate Right/Left DMA Channels  *
  2847.          *=======================================*/
  2848.         case 1:
  2849.                 dmaRight = kmem_alloc (DMA_BUF_SIZE, 
  2850.                                    KM_NOSLEEP | KM_PHYSCONTIG | KM_CACHEALIGN );
  2851.  
  2852.                 if ( dmaRight == (caddr_t)NULL ) {
  2853.                         cmn_err (CE_WARN, 
  2854.                          "rapKernMem: Cannot allocate DMA memory for R_chann");
  2855.                          return(1);
  2856.                     }
  2857.  
  2858.                     dmaLeft = kmem_alloc (DMA_BUF_SIZE,
  2859.                                    KM_NOSLEEP | KM_PHYSCONTIG | KM_CACHEALIGN );
  2860.                     if ( dmaLeft == (caddr_t)NULL ) {
  2861.                             cmn_err (CE_WARN,
  2862.                          "rapKernMem: Cannot allocate DMA memory for L_chann");
  2863.              kmem_free (dmaRight, DMA_BUF_SIZE);
  2864.                          return(1);
  2865.                     }
  2866.  
  2867.             /*   get the physicall address  */
  2868.             dmaRightPhys = kvtophys(dmaRight);
  2869.             dmaLeftPhys  = kvtophys(dmaLeft);
  2870.  
  2871.             return(0);
  2872.  
  2873.                 /*=======================================*
  2874.                  *   Deallocate Right/Left DMA Channels  *
  2875.                  *=======================================*/
  2876.         case 2:
  2877.              if ( dmaRight != NULL ) {
  2878.             kmem_free (dmaRight, DMA_BUF_SIZE);
  2879.             dmaRight = (caddr_t)NULL;
  2880.              }
  2881.              if ( dmaLeft != NULL ) {
  2882.             kmem_free (dmaLeft, DMA_BUF_SIZE);
  2883.             dmaLeft = (caddr_t)NULL;
  2884.              }
  2885.         
  2886.              return(0);
  2887.  
  2888.      }  /* switch */
  2889.  
  2890.  
  2891. }  /***   End rapKernMem   ***/
  2892.  
  2893.  
  2894. /*************************************************************************
  2895.  *            r a p T i m e O u t           
  2896.  *************************************************************************
  2897.  *
  2898.  *  Name:       rapTimeOut
  2899.  *    
  2900.  *  Purpose:    is called when Read/Write waiting for buffers time out.
  2901.  *
  2902.  *  Returns:   
  2903.  *
  2904.  *************************************************************************/
  2905. static void
  2906. rapTimeOut( void *addr )
  2907. {
  2908.     cardInfo_t    *ci;
  2909.  
  2910.     ci = &cardInfo;
  2911.  
  2912.     /*   indicate a timeout  */
  2913.     ci->ri_tout = 1;
  2914.     wakeup (addr);
  2915.  
  2916. }
  2917.     
  2918.  
  2919. /*************************************************************************
  2920.  *                      r a p N o t e O n    
  2921.  *************************************************************************
  2922.  *
  2923.  *  Name:       rapNoteOn 
  2924.  *
  2925.  *  Purpose:    Sends a MIDI Note_On message.
  2926.  *        This code is taken from RAP-10 manual.
  2927.  *
  2928.  *  Returns:    None.
  2929.  *
  2930.  *************************************************************************/
  2931. static void
  2932. rapNoteOn ( cardInfo_t  *ci, ushort_t orig_gpis)
  2933. {
  2934.     int        s, stereo;
  2935.     uchar_t     c, pan, rank, chksum, sum;
  2936.     caddr_t     addr;
  2937.     ushort_t    gpis;
  2938.  
  2939.     addr = ci->ci_addr[0];
  2940.     stereo = ci->ci_state & CARD_STEREO;
  2941.     pan = 0x40;
  2942.     rank = 0x01;    /* for 22050 Hz  */
  2943.     gpis = orig_gpis;
  2944.  
  2945.     /*
  2946.      *      Busy wait till Txd Fifo is empty
  2947.      *    The interrupt version is commenetd out below
  2948.      */ 
  2949.  
  2950.         #ifdef DEBUG
  2951.         cmn_err (CE_NOTE, "rapNoteOn: Waiting for Txd Fifo Empty, gpis = %x",
  2952.          gpis);
  2953.         #endif
  2954.  
  2955.     while ( !(gpis & GPIS_TXD) ) {
  2956.         gpis = INPW(addr+GPIS);
  2957.  
  2958.             #ifdef DEBUG
  2959.             cmn_err (CE_NOTE, "rapNoteOn: Waiting ..new gpis = %x", gpis); 
  2960.             #endif
  2961.     }
  2962.  
  2963.  
  2964.     #ifdef DEBUG
  2965.     cmn_err (CE_NOTE, "rapNoteOn: Issuing a Note_On SysEx Cmd");
  2966.     #endif
  2967.  
  2968.     /*   send Note_On   */
  2969.     c = 0xf0; OUTB(addr+MDTD, c);    
  2970.     c = 0x41; OUTB(addr+MDTD, c); 
  2971.     c = 0x10; OUTB(addr+MDTD, c); 
  2972.     c = 0x56; OUTB(addr+MDTD, c); 
  2973.     c = 0x12; OUTB(addr+MDTD, c);     
  2974.  
  2975.     if ( stereo ) { 
  2976.         c = 0x03; OUTB(addr+MDTD, c); 
  2977.         c = 0x00; OUTB(addr+MDTD, c);
  2978.         c = 0x01; OUTB(addr+MDTD, c); 
  2979.         sum = 0x03 + 0x01;
  2980.     }
  2981.     else {
  2982.         c = 0x02; OUTB(addr+MDTD, c); 
  2983.         c = 0x00; OUTB(addr+MDTD, c); 
  2984.         c = 0x0A+0x01; OUTB(addr+MDTD, c); 
  2985.         sum = 0x02+0x0A+0x01;
  2986.     }
  2987.     
  2988.     c = 0x01; OUTB(addr+MDTD, c);
  2989.     c = 0x7F; OUTB(addr+MDTD, c); 
  2990.     c = 0x7F; OUTB(addr+MDTD, c); 
  2991.               OUTB(addr+MDTD, rank); 
  2992.     sum += (0x01+0x7F+0x7F+rank);
  2993.  
  2994.     c = 0x40; OUTB(addr+MDTD, c); 
  2995.     c = 0x00; OUTB(addr+MDTD, c);
  2996.     c = 0x40; OUTB(addr+MDTD, c); 
  2997.               OUTB(addr+MDTD, pan);  
  2998.     sum += (0x40+0x40+pan);
  2999.  
  3000.     /*  calculate the checksum  */
  3001.     chksum = (0x80 - (sum % 0x80)) & 0x7F;
  3002.     OUTB(addr+MDTD, chksum); 
  3003.     c = 0xF7; OUTB(addr+MDTD, c); 
  3004.  
  3005.     #ifdef DEBUG
  3006.     cmn_err (CE_NOTE, "rapNoteOn: Note_On Issued, chksum = %x", chksum);
  3007.     #endif
  3008.  
  3009. }  /* end rapNoteOn  */
  3010.  
  3011. /*************************************************************************
  3012.  *                      r a p N o t e O f f  
  3013.  *************************************************************************
  3014.  *
  3015.  *  Name:       rapNoteOff
  3016.  *
  3017.  *  Purpose:    Sends a MIDI Note_Off message.
  3018.  *        This code is taken from RAP-10 manual.
  3019.  *
  3020.  *  Returns:    None.
  3021.  *
  3022.  *************************************************************************/
  3023. static void
  3024. rapNoteOff ( cardInfo_t  *ci)
  3025. {
  3026.     int        s, stereo;
  3027.     uchar_t     pan, b, rank, sum, chksum;
  3028.     caddr_t     addr;
  3029.     ushort_t    gpis;
  3030.  
  3031.     addr = ci->ci_addr[0];
  3032.     stereo = ci->ci_state & CARD_STEREO;
  3033.     pan = 0x40;
  3034.     rank = 0x01;    /* for 22050 Hz  */
  3035.  
  3036.     #ifdef DEBUG
  3037.     cmn_err (CE_NOTE, "rapNoteOff: Waiting for Txd Empty");
  3038.     #endif
  3039.  
  3040.         /*  wait till Txd is Empty   */
  3041.         gpis = INPW(addr+GPIS);
  3042.         while ( !(gpis & GPIS_TXD) ) {
  3043.                 us_delay(10);
  3044.                 gpis = INPW(addr+GPIS);
  3045.  
  3046.                 #ifdef DEBUG
  3047.                 cmn_err (CE_NOTE, "rapNoteOff: Waiting ..new gpis = %x", gpis);
  3048.                 #endif
  3049.  
  3050.         }
  3051.  
  3052.     #ifdef DEBUG
  3053.     cmn_err (CE_NOTE, "rapNoteOff: Issuing Note_Off");
  3054.     #endif
  3055.  
  3056.     /*   send Note_On   */
  3057.     OUTB(addr+MDTD, 0xF0);
  3058.     OUTB(addr+MDTD, 0x41);
  3059.     OUTB(addr+MDTD, 0x10);
  3060.     OUTB(addr+MDTD, 0x56);
  3061.     OUTB(addr+MDTD, 0x12);
  3062.  
  3063.     if ( stereo ) { 
  3064.         OUTB(addr+MDTD, 0x03);
  3065.         OUTB(addr+MDTD, 0x00);
  3066.         OUTB(addr+MDTD, 0x01);
  3067.         sum = 0x03 + 0x01;
  3068.     }
  3069.     else {
  3070.         OUTB(addr+MDTD, 0x02);
  3071.         OUTB(addr+MDTD, 0x00);
  3072.         OUTB(addr+MDTD, 0x0A+0x01);
  3073.         sum = 0x02 + 0x0A + 0x01;
  3074.     }
  3075.     
  3076.     OUTB(addr+MDTD, 0x00);
  3077.     OUTB(addr+MDTD, 0x7F);
  3078.     OUTB(addr+MDTD, 0x7F);
  3079.     OUTB(addr+MDTD, 0x00);
  3080.     sum += 0x7F + 0x7F;
  3081.  
  3082.     OUTB(addr+MDTD, 0x40);
  3083.     OUTB(addr+MDTD, 0x00);
  3084.     OUTB(addr+MDTD, 0x40);
  3085.     OUTB(addr+MDTD, pan); 
  3086.     sum += 0x40 + 0x40 + pan;
  3087.  
  3088.     /*   calculate checksum   */
  3089.         /*  calculate the checksum  */
  3090.         chksum = (0x80 - (sum % 0x80)) & 0x7F;
  3091.         OUTB(addr+MDTD, chksum);
  3092.         OUTB(addr+MDTD, 0x7F);
  3093.  
  3094.         #ifdef DEBUG
  3095.         cmn_err (CE_NOTE, "rapNoteOff: Note_On Issued, chksum = %x", chksum);
  3096.         #endif
  3097.  
  3098. }  /*  end rapNoteOff  */
  3099.  
  3100. /*************************************************************************
  3101.  *                      r a p Z e r o D m a           
  3102.  *************************************************************************
  3103.  *
  3104.  *  Name:      rapZeroDma 
  3105.  *
  3106.  *  Purpose:   Zero outs DMA buffers. 
  3107.  *
  3108.  *  Returns:   None.
  3109.  *
  3110.  *************************************************************************/
  3111. static void
  3112. rapZeroDma (cardInfo_t *ci, int bytes)
  3113. {
  3114.  
  3115.     caddr_t    dmaL, dmaR;
  3116.     int       stereo, s;
  3117.  
  3118.     s = LOCK();
  3119.  
  3120.     stereo = ci->ci_state & CARD_STEREO;
  3121.  
  3122.  
  3123.         /*
  3124.          *     Zero out which half ?  
  3125.          */
  3126.         if ( ci->di_which ) {
  3127.                dmaR = &dmaRight[DMA_HALF_SIZE];
  3128.                dmaL = &dmaLeft[DMA_HALF_SIZE];
  3129.                if ( bytes == DMA_BUF_SIZE ) {
  3130.                     bytes = DMA_HALF_SIZE;
  3131.                }
  3132.         }
  3133.         /*  Zer out 1st half of dma buffers */
  3134.         else {
  3135.             dmaR = &dmaRight[0];
  3136.             dmaL = &dmaLeft[0];
  3137.         }
  3138.     
  3139.  
  3140.     #ifdef DEBUG
  3141.     cmn_err (CE_NOTE, 
  3142.          "rapZeroDma: Zeroing out %s of Dma buffers in %s for %d bytes",
  3143.          (ci->di_which ? "2nd half":"1st half"),
  3144.          (stereo ? "Stereo":"Mono"),
  3145.          bytes);
  3146.     #endif
  3147.  
  3148.     bzero (dmaL, bytes);
  3149.     dki_dcache_wbinval (dmaL, (unsigned)bytes);
  3150.  
  3151.     if ( stereo ) { 
  3152.         bzero (dmaR, bytes);
  3153.         dki_dcache_wbinval (dmaR, (unsigned)bytes);
  3154.     }
  3155.  
  3156.     UNLOCK(s);
  3157. }
  3158.  
  3159. /*************************************************************************
  3160.  *                      r a p R e l e a s e D m a  
  3161.  *************************************************************************
  3162.  *
  3163.  *  Name:      rapReleaseDma
  3164.  *
  3165.  *  Purpose:   Releases Dma channel(s).   
  3166.  *             Note that we access kernel's Dma structure and later on   
  3167.  *             a routine will be provided for us to avoid this.
  3168.  *
  3169.  *  Returns:   None.
  3170.  *
  3171.  *************************************************************************/
  3172. static void
  3173. rapReleaseDma (cardInfo_t *ci)
  3174. {
  3175.  
  3176.     
  3177.         /*   disable Eisa Dma  */
  3178.         #ifdef DEBUG
  3179.         cmn_err (CE_NOTE, "rapReleaseDma: Releasing Eisa Dma Chann %d",
  3180.                  ci->ci_dmaCh5);
  3181.         #endif
  3182.  
  3183.      /*  eisa_dma_disable(0, ci->ci_dmaCh5);  */
  3184.         vsema(&e_ch[ci->ci_dmaCh5].chan_sem);
  3185.  
  3186.         if ( ci->ci_state & CARD_STEREO ) {
  3187.                 #ifdef DEBUG
  3188.                 cmn_err (CE_NOTE, "rapReleaseDma: Releasing Eisa Dma Chann %d",
  3189.                         ci->ci_dmaCh6);
  3190.                 #endif
  3191.  
  3192.          /*   eisa_dma_disable(0, ci->ci_dmaCh6);  */
  3193.                 vsema (&e_ch[ci->ci_dmaCh6].chan_sem);
  3194.         }
  3195.  
  3196. }
  3197.  
  3198. /*************************************************************************
  3199.  *            r a p S e t A u t o I n i t 
  3200.  *************************************************************************
  3201.  *
  3202.  *  Name:      rapSetAutoInit
  3203.  *    
  3204.  *  Purpose:   sets Eisa DMA register for Autoinit. In Autoinit, DMA 
  3205.  *           starts over from the beginning of the buffer again once it
  3206.  *           has transfered all bytes in the buffer.
  3207.  *
  3208.  *  Returns:   None.
  3209.  *
  3210.  *************************************************************************/
  3211. #define  EISA_MODE_REG  0xd6
  3212. #define  EISA_CH5       0x01
  3213. #define  EISA_CH6       0x02
  3214. #define  EISA_WRITE     0x04
  3215. #define  EISA_READ      0x08
  3216. #define  EISA_AUTO      0x10
  3217.  
  3218. static void 
  3219. rapSetAutoInit( cardInfo_t  *ci, uchar_t what)
  3220. {
  3221.     uchar_t    b;
  3222.  
  3223. #ifdef DEBUG
  3224.     cmn_err (CE_NOTE,
  3225.     "rapSetAutoInit: setting Autoinit DMA for %s, Eisa Addr = %x",
  3226.     ( what == DI_DMA_PLAYING ? "Playback(D/A)" : "Record(A/D)" ),
  3227.     eisa_addr );
  3228. #endif
  3229.  
  3230.  
  3231.     b = 0;
  3232.     if ( what == DI_DMA_PLAYING )
  3233.         b |= EISA_READ;        /*  Memory -> Device  */
  3234.     else    b |= EISA_WRITE;       /*  Device -> Memory  */
  3235.  
  3236.     /*   Autoinit for Channel 5 - Demand Mode select is default    */
  3237.     b |= (EISA_AUTO | EISA_CH5);
  3238.     OUTB(eisa_addr+EISA_MODE_REG, b);
  3239.  
  3240.  
  3241.     /*   Autoinit for Channel 6 (if in stereo mode)  */
  3242.     if ( ci->ci_state & CARD_STEREO ) {
  3243.         b &= ~EISA_CH5;
  3244.         b |= EISA_CH6;
  3245.         OUTB(eisa_addr+EISA_MODE_REG, b);
  3246.     }
  3247.  
  3248.  
  3249. }  /***   End rapSetAutoInit   ***/
  3250.  
  3251.